Directory: | ../../../ffmpeg/ |
---|---|
File: | src/libavcodec/cbs_sei_syntax_template.c |
Date: | 2022-07-05 19:52:29 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 99 | 141 | 70.2% |
Branches: | 36 | 90 | 40.0% |
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 | ✗ | static int FUNC(filler_payload) | |
20 | (CodedBitstreamContext *ctx, RWContext *rw, | ||
21 | SEIRawFillerPayload *current, SEIMessageState *state) | ||
22 | { | ||
23 | int err, i; | ||
24 | |||
25 | ✗ | HEADER("Filler Payload"); | |
26 | |||
27 | #ifdef READ | ||
28 | ✗ | current->payload_size = state->payload_size; | |
29 | #endif | ||
30 | |||
31 | ✗ | for (i = 0; i < current->payload_size; i++) | |
32 | ✗ | fixed(8, ff_byte, 0xff); | |
33 | |||
34 | ✗ | return 0; | |
35 | } | ||
36 | |||
37 | 150 | static int FUNC(user_data_registered) | |
38 | (CodedBitstreamContext *ctx, RWContext *rw, | ||
39 | SEIRawUserDataRegistered *current, SEIMessageState *state) | ||
40 | { | ||
41 | int err, i, j; | ||
42 | |||
43 | 150 | HEADER("User Data Registered ITU-T T.35"); | |
44 | |||
45 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 75 times.
|
150 | u(8, itu_t_t35_country_code, 0x00, 0xff); |
46 |
1/2✓ Branch 0 taken 75 times.
✗ Branch 1 not taken.
|
150 | if (current->itu_t_t35_country_code != 0xff) |
47 | 150 | i = 1; | |
48 | else { | ||
49 | ✗ | u(8, itu_t_t35_country_code_extension_byte, 0x00, 0xff); | |
50 | ✗ | i = 2; | |
51 | } | ||
52 | |||
53 | #ifdef READ | ||
54 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 25 times.
|
50 | if (state->payload_size < i) { |
55 | ✗ | av_log(ctx->log_ctx, AV_LOG_ERROR, | |
56 | "Invalid SEI user data registered payload.\n"); | ||
57 | ✗ | return AVERROR_INVALIDDATA; | |
58 | } | ||
59 | 50 | current->data_length = state->payload_size - i; | |
60 | #endif | ||
61 | |||
62 |
2/3✗ Branch 0 not taken.
✓ Branch 1 taken 50 times.
✓ Branch 2 taken 25 times.
|
150 | allocate(current->data, current->data_length); |
63 |
2/2✓ Branch 0 taken 729 times.
✓ Branch 1 taken 75 times.
|
1608 | for (j = 0; j < current->data_length; j++) |
64 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 729 times.
|
1458 | xu(8, itu_t_t35_payload_byte[], current->data[j], 0x00, 0xff, 1, i + j); |
65 | |||
66 | 150 | return 0; | |
67 | } | ||
68 | |||
69 | ✗ | static int FUNC(user_data_unregistered) | |
70 | (CodedBitstreamContext *ctx, RWContext *rw, | ||
71 | SEIRawUserDataUnregistered *current, SEIMessageState *state) | ||
72 | { | ||
73 | int err, i; | ||
74 | |||
75 | ✗ | HEADER("User Data Unregistered"); | |
76 | |||
77 | #ifdef READ | ||
78 | ✗ | if (state->payload_size < 16) { | |
79 | ✗ | av_log(ctx->log_ctx, AV_LOG_ERROR, | |
80 | "Invalid SEI user data unregistered payload.\n"); | ||
81 | ✗ | return AVERROR_INVALIDDATA; | |
82 | } | ||
83 | ✗ | current->data_length = state->payload_size - 16; | |
84 | #endif | ||
85 | |||
86 | ✗ | for (i = 0; i < 16; i++) | |
87 | ✗ | us(8, uuid_iso_iec_11578[i], 0x00, 0xff, 1, i); | |
88 | |||
89 | ✗ | allocate(current->data, current->data_length); | |
90 | |||
91 | ✗ | for (i = 0; i < current->data_length; i++) | |
92 | ✗ | xu(8, user_data_payload_byte[i], current->data[i], 0x00, 0xff, 1, i); | |
93 | |||
94 | ✗ | return 0; | |
95 | } | ||
96 | |||
97 | 6 | static int FUNC(mastering_display_colour_volume) | |
98 | (CodedBitstreamContext *ctx, RWContext *rw, | ||
99 | SEIRawMasteringDisplayColourVolume *current, SEIMessageState *state) | ||
100 | { | ||
101 | int err, c; | ||
102 | |||
103 | 6 | HEADER("Mastering Display Colour Volume"); | |
104 | |||
105 |
2/2✓ Branch 0 taken 9 times.
✓ Branch 1 taken 3 times.
|
24 | for (c = 0; c < 3; c++) { |
106 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
|
18 | ubs(16, display_primaries_x[c], 1, c); |
107 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
|
18 | ubs(16, display_primaries_y[c], 1, c); |
108 | } | ||
109 | |||
110 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
|
6 | ub(16, white_point_x); |
111 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
|
6 | ub(16, white_point_y); |
112 | |||
113 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
|
6 | ub(32, max_display_mastering_luminance); |
114 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
|
6 | ub(32, min_display_mastering_luminance); |
115 | |||
116 | 6 | return 0; | |
117 | } | ||
118 | |||
119 | ✗ | static int FUNC(content_light_level_info) | |
120 | (CodedBitstreamContext *ctx, RWContext *rw, | ||
121 | SEIRawContentLightLevelInfo *current, SEIMessageState *state) | ||
122 | { | ||
123 | int err; | ||
124 | |||
125 | ✗ | HEADER("Content Light Level Information"); | |
126 | |||
127 | ✗ | ub(16, max_content_light_level); | |
128 | ✗ | ub(16, max_pic_average_light_level); | |
129 | |||
130 | ✗ | return 0; | |
131 | } | ||
132 | |||
133 | ✗ | static int FUNC(alternative_transfer_characteristics) | |
134 | (CodedBitstreamContext *ctx, RWContext *rw, | ||
135 | SEIRawAlternativeTransferCharacteristics *current, | ||
136 | SEIMessageState *state) | ||
137 | { | ||
138 | int err; | ||
139 | |||
140 | ✗ | HEADER("Alternative Transfer Characteristics"); | |
141 | |||
142 | ✗ | ub(8, preferred_transfer_characteristics); | |
143 | |||
144 | ✗ | return 0; | |
145 | } | ||
146 | |||
147 | 11396 | static int FUNC(message)(CodedBitstreamContext *ctx, RWContext *rw, | |
148 | SEIRawMessage *current) | ||
149 | { | ||
150 | const SEIMessageTypeDescriptor *desc; | ||
151 | int err, i; | ||
152 | |||
153 | 11396 | desc = ff_cbs_sei_find_type(ctx, current->payload_type); | |
154 |
2/2✓ Branch 0 taken 5683 times.
✓ Branch 1 taken 15 times.
|
11396 | if (desc) { |
155 | 11366 | SEIMessageState state = { | |
156 | 11366 | .payload_type = current->payload_type, | |
157 | 11366 | .payload_size = current->payload_size, | |
158 | 11366 | .extension_present = current->extension_bit_length > 0, | |
159 | }; | ||
160 | int start_position, current_position, bits_written; | ||
161 | |||
162 | #ifdef READ | ||
163 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1895 times.
|
3790 | CHECK(ff_cbs_sei_alloc_message_payload(current, desc)); |
164 | #endif | ||
165 | |||
166 | 11366 | start_position = bit_position(rw); | |
167 | |||
168 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 5683 times.
|
11366 | CHECK(desc->READWRITE(ctx, rw, current->payload, &state)); |
169 | |||
170 | 11366 | current_position = bit_position(rw); | |
171 | 11366 | bits_written = current_position - start_position; | |
172 | |||
173 |
3/4✓ Branch 1 taken 4230 times.
✓ Branch 2 taken 1453 times.
✓ Branch 3 taken 4230 times.
✗ Branch 4 not taken.
|
11366 | if (byte_alignment(rw) || state.extension_present || |
174 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4230 times.
|
8460 | bits_written < 8 * current->payload_size) { |
175 | size_t bits_left; | ||
176 | |||
177 | #ifdef READ | ||
178 | 970 | GetBitContext tmp = *rw; | |
179 | int trailing_bits, trailing_zero_bits; | ||
180 | |||
181 | 970 | bits_left = 8 * current->payload_size - bits_written; | |
182 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 485 times.
|
970 | if (bits_left > 8) |
183 | ✗ | skip_bits_long(&tmp, bits_left - 8); | |
184 | 970 | trailing_bits = get_bits(&tmp, FFMIN(bits_left, 8)); | |
185 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 485 times.
|
970 | if (trailing_bits == 0) { |
186 | // The trailing bits must contain a bit_equal_to_one, so | ||
187 | // they can't all be zero. | ||
188 | ✗ | return AVERROR_INVALIDDATA; | |
189 | } | ||
190 | 970 | trailing_zero_bits = ff_ctz(trailing_bits); | |
191 | 970 | current->extension_bit_length = | |
192 | 970 | bits_left - 1 - trailing_zero_bits; | |
193 | #endif | ||
194 | |||
195 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1453 times.
|
2906 | if (current->extension_bit_length > 0) { |
196 | ✗ | allocate(current->extension_data, | |
197 | (current->extension_bit_length + 7) / 8); | ||
198 | |||
199 | ✗ | bits_left = current->extension_bit_length; | |
200 | ✗ | for (i = 0; bits_left > 0; i++) { | |
201 | ✗ | int length = FFMIN(bits_left, 8); | |
202 | ✗ | xu(length, reserved_payload_extension_data, | |
203 | current->extension_data[i], | ||
204 | 0, MAX_UINT_BITS(length), 0); | ||
205 | ✗ | bits_left -= length; | |
206 | } | ||
207 | } | ||
208 | |||
209 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1453 times.
|
2906 | fixed(1, bit_equal_to_one, 1); |
210 |
2/2✓ Branch 1 taken 3002 times.
✓ Branch 2 taken 1453 times.
|
8910 | while (byte_alignment(rw)) |
211 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 3002 times.
|
6004 | fixed(1, bit_equal_to_zero, 0); |
212 | } | ||
213 | |||
214 | #ifdef WRITE | ||
215 | 7576 | current->payload_size = (put_bits_count(rw) - start_position) / 8; | |
216 | #endif | ||
217 | } else { | ||
218 | uint8_t *data; | ||
219 | |||
220 |
2/3✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 5 times.
|
30 | allocate(current->payload, current->payload_size); |
221 | 30 | data = current->payload; | |
222 | |||
223 |
2/2✓ Branch 0 taken 5232 times.
✓ Branch 1 taken 15 times.
|
10494 | for (i = 0; i < current->payload_size; i++) |
224 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 5232 times.
|
10464 | xu(8, payload_byte[i], data[i], 0, 255, 1, i); |
225 | } | ||
226 | |||
227 | 11396 | return 0; | |
228 | } | ||
229 | |||
230 | 3759 | static int FUNC(message_list)(CodedBitstreamContext *ctx, RWContext *rw, | |
231 | SEIRawMessageList *current, int prefix) | ||
232 | { | ||
233 | SEIRawMessage *message; | ||
234 | int err, k; | ||
235 | |||
236 | #ifdef READ | ||
237 | 1900 | for (k = 0;; k++) { | |
238 | 1900 | uint32_t payload_type = 0; | |
239 | 1900 | uint32_t payload_size = 0; | |
240 | uint32_t tmp; | ||
241 | GetBitContext payload_gbc; | ||
242 | |||
243 | 1920 | while (show_bits(rw, 8) == 0xff) { | |
244 | 20 | fixed(8, ff_byte, 0xff); | |
245 | 20 | payload_type += 255; | |
246 | } | ||
247 | 1900 | xu(8, last_payload_type_byte, tmp, 0, 254, 0); | |
248 | 1900 | payload_type += tmp; | |
249 | |||
250 | 1905 | while (show_bits(rw, 8) == 0xff) { | |
251 | 5 | fixed(8, ff_byte, 0xff); | |
252 | 5 | payload_size += 255; | |
253 | } | ||
254 | 1900 | xu(8, last_payload_size_byte, tmp, 0, 254, 0); | |
255 | 1900 | payload_size += tmp; | |
256 | |||
257 | // There must be space remaining for both the payload and | ||
258 | // the trailing bits on the SEI NAL unit. | ||
259 | 1900 | if (payload_size + 1 > get_bits_left(rw) / 8) { | |
260 | ✗ | av_log(ctx->log_ctx, AV_LOG_ERROR, | |
261 | "Invalid SEI message: payload_size too large " | ||
262 | "(%"PRIu32" bytes).\n", payload_size); | ||
263 | ✗ | return AVERROR_INVALIDDATA; | |
264 | } | ||
265 | 1900 | CHECK(init_get_bits(&payload_gbc, rw->buffer, | |
266 | get_bits_count(rw) + 8 * payload_size)); | ||
267 | 1900 | skip_bits_long(&payload_gbc, get_bits_count(rw)); | |
268 | |||
269 | 1900 | CHECK(ff_cbs_sei_list_add(current)); | |
270 | 1900 | message = ¤t->messages[k]; | |
271 | |||
272 | 1900 | message->payload_type = payload_type; | |
273 | 1900 | message->payload_size = payload_size; | |
274 | |||
275 | 1900 | CHECK(FUNC(message)(ctx, &payload_gbc, message)); | |
276 | |||
277 | 1900 | skip_bits_long(rw, 8 * payload_size); | |
278 | |||
279 | 1900 | if (!cbs_h2645_read_more_rbsp_data(rw)) | |
280 | 1880 | break; | |
281 | } | ||
282 | #else | ||
283 | 3778 | for (k = 0; k < current->nb_messages; k++) { | |
284 | PutBitContext start_state; | ||
285 | uint32_t tmp; | ||
286 | int trace, i; | ||
287 | |||
288 | 1899 | message = ¤t->messages[k]; | |
289 | |||
290 | // We write the payload twice in order to find the size. Trace | ||
291 | // output is switched off for the first write. | ||
292 | 1899 | trace = ctx->trace_enable; | |
293 | 1899 | ctx->trace_enable = 0; | |
294 | |||
295 | 1899 | start_state = *rw; | |
296 | 5697 | for (i = 0; i < 2; i++) { | |
297 | 3798 | *rw = start_state; | |
298 | |||
299 | 3798 | tmp = message->payload_type; | |
300 | 3838 | while (tmp >= 255) { | |
301 | 40 | fixed(8, ff_byte, 0xff); | |
302 | 40 | tmp -= 255; | |
303 | } | ||
304 | 3798 | xu(8, last_payload_type_byte, tmp, 0, 254, 0); | |
305 | |||
306 | 3798 | tmp = message->payload_size; | |
307 | 3808 | while (tmp >= 255) { | |
308 | 10 | fixed(8, ff_byte, 0xff); | |
309 | 10 | tmp -= 255; | |
310 | } | ||
311 | 3798 | xu(8, last_payload_size_byte, tmp, 0, 254, 0); | |
312 | |||
313 | 3798 | err = FUNC(message)(ctx, rw, message); | |
314 | 3798 | ctx->trace_enable = trace; | |
315 | 3798 | if (err < 0) | |
316 | ✗ | return err; | |
317 | } | ||
318 | } | ||
319 | #endif | ||
320 | |||
321 | 3759 | return 0; | |
322 | } | ||
323 |