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 | 120 | static int FUNC(user_data_unregistered) | |
70 | (CodedBitstreamContext *ctx, RWContext *rw, | ||
71 | SEIRawUserDataUnregistered *current, SEIMessageState *state) | ||
72 | { | ||
73 | int err, i; | ||
74 | |||
75 | 120 | HEADER("User Data Unregistered"); | |
76 | |||
77 | #ifdef READ | ||
78 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
|
40 | 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 | 40 | current->data_length = state->payload_size - 16; | |
84 | #endif | ||
85 | |||
86 |
2/2✓ Branch 0 taken 960 times.
✓ Branch 1 taken 60 times.
|
2040 | for (i = 0; i < 16; i++) |
87 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 960 times.
|
1920 | us(8, uuid_iso_iec_11578[i], 0x00, 0xff, 1, i); |
88 | |||
89 |
2/3✗ Branch 0 not taken.
✓ Branch 1 taken 40 times.
✓ Branch 2 taken 20 times.
|
120 | allocate(current->data, current->data_length); |
90 | |||
91 |
2/2✓ Branch 0 taken 14379 times.
✓ Branch 1 taken 60 times.
|
28878 | for (i = 0; i < current->data_length; i++) |
92 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 14379 times.
|
28758 | xu(8, user_data_payload_byte[i], current->data[i], 0x00, 0xff, 1, i); |
93 | |||
94 | 120 | 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 | ✗ | static int FUNC(ambient_viewing_environment) | |
148 | (CodedBitstreamContext *ctx, RWContext *rw, | ||
149 | SEIRawAmbientViewingEnvironment *current, | ||
150 | SEIMessageState *state) | ||
151 | { | ||
152 | static const uint16_t max_ambient_light_value = 50000; | ||
153 | int err; | ||
154 | |||
155 | ✗ | HEADER("Ambient Viewing Environment"); | |
156 | |||
157 | ✗ | u(32, ambient_illuminance, 1, MAX_UINT_BITS(32)); | |
158 | ✗ | u(16, ambient_light_x, 0, max_ambient_light_value); | |
159 | ✗ | u(16, ambient_light_y, 0, max_ambient_light_value); | |
160 | |||
161 | ✗ | return 0; | |
162 | } | ||
163 | |||
164 | 26808 | static int FUNC(message)(CodedBitstreamContext *ctx, RWContext *rw, | |
165 | SEIRawMessage *current) | ||
166 | { | ||
167 | const SEIMessageTypeDescriptor *desc; | ||
168 | int err, i; | ||
169 | |||
170 | 26808 | desc = ff_cbs_sei_find_type(ctx, current->payload_type); | |
171 |
2/2✓ Branch 0 taken 13203 times.
✓ Branch 1 taken 201 times.
|
26808 | if (desc) { |
172 | 26406 | SEIMessageState state = { | |
173 | 26406 | .payload_type = current->payload_type, | |
174 | 26406 | .payload_size = current->payload_size, | |
175 | 26406 | .extension_present = current->extension_bit_length > 0, | |
176 | }; | ||
177 | int start_position, current_position, bits_written; | ||
178 | |||
179 | #ifdef READ | ||
180 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 4783 times.
|
9566 | CHECK(ff_cbs_sei_alloc_message_payload(current, desc)); |
181 | #endif | ||
182 | |||
183 | 26406 | start_position = bit_position(rw); | |
184 | |||
185 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 13203 times.
|
26406 | CHECK(desc->READWRITE(ctx, rw, current->payload, &state)); |
186 | |||
187 | 26406 | current_position = bit_position(rw); | |
188 | 26406 | bits_written = current_position - start_position; | |
189 | |||
190 |
3/4✓ Branch 1 taken 10920 times.
✓ Branch 2 taken 2283 times.
✓ Branch 3 taken 10920 times.
✗ Branch 4 not taken.
|
26406 | if (byte_alignment(rw) || state.extension_present || |
191 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10920 times.
|
21840 | bits_written < 8 * current->payload_size) { |
192 | size_t bits_left; | ||
193 | |||
194 | #ifdef READ | ||
195 | 2066 | GetBitContext tmp = *rw; | |
196 | int trailing_bits, trailing_zero_bits; | ||
197 | |||
198 | 2066 | bits_left = 8 * current->payload_size - bits_written; | |
199 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1033 times.
|
2066 | if (bits_left > 8) |
200 | ✗ | skip_bits_long(&tmp, bits_left - 8); | |
201 | 2066 | trailing_bits = get_bits(&tmp, FFMIN(bits_left, 8)); | |
202 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1033 times.
|
2066 | if (trailing_bits == 0) { |
203 | // The trailing bits must contain a bit_equal_to_one, so | ||
204 | // they can't all be zero. | ||
205 | ✗ | return AVERROR_INVALIDDATA; | |
206 | } | ||
207 | 2066 | trailing_zero_bits = ff_ctz(trailing_bits); | |
208 | 2066 | current->extension_bit_length = | |
209 | 2066 | bits_left - 1 - trailing_zero_bits; | |
210 | #endif | ||
211 | |||
212 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2283 times.
|
4566 | if (current->extension_bit_length > 0) { |
213 | ✗ | allocate(current->extension_data, | |
214 | (current->extension_bit_length + 7) / 8); | ||
215 | |||
216 | ✗ | bits_left = current->extension_bit_length; | |
217 | ✗ | for (i = 0; bits_left > 0; i++) { | |
218 | ✗ | int length = FFMIN(bits_left, 8); | |
219 | ✗ | xu(length, reserved_payload_extension_data, | |
220 | current->extension_data[i], | ||
221 | 0, MAX_UINT_BITS(length), 0); | ||
222 | ✗ | bits_left -= length; | |
223 | } | ||
224 | } | ||
225 | |||
226 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2283 times.
|
4566 | fixed(1, bit_equal_to_one, 1); |
227 |
2/2✓ Branch 1 taken 3102 times.
✓ Branch 2 taken 2283 times.
|
10770 | while (byte_alignment(rw)) |
228 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 3102 times.
|
6204 | fixed(1, bit_equal_to_zero, 0); |
229 | } | ||
230 | |||
231 | #ifdef WRITE | ||
232 | 16840 | current->payload_size = (put_bits_count(rw) - start_position) / 8; | |
233 | #endif | ||
234 | } else { | ||
235 | uint8_t *data; | ||
236 | |||
237 |
2/3✗ Branch 0 not taken.
✓ Branch 1 taken 134 times.
✓ Branch 2 taken 67 times.
|
402 | allocate(current->payload, current->payload_size); |
238 | 402 | data = current->payload; | |
239 | |||
240 |
2/2✓ Branch 0 taken 6033 times.
✓ Branch 1 taken 201 times.
|
12468 | for (i = 0; i < current->payload_size; i++) |
241 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 6033 times.
|
12066 | xu(8, payload_byte[i], data[i], 0, 255, 1, i); |
242 | } | ||
243 | |||
244 | 26808 | return 0; | |
245 | } | ||
246 | |||
247 | 9087 | static int FUNC(message_list)(CodedBitstreamContext *ctx, RWContext *rw, | |
248 | SEIRawMessageList *current, int prefix) | ||
249 | { | ||
250 | SEIRawMessage *message; | ||
251 | int err, k; | ||
252 | |||
253 | #ifdef READ | ||
254 | 4850 | for (k = 0;; k++) { | |
255 | 4850 | uint32_t payload_type = 0; | |
256 | 4850 | uint32_t payload_size = 0; | |
257 | uint32_t tmp; | ||
258 | GetBitContext payload_gbc; | ||
259 | |||
260 | 4870 | while (show_bits(rw, 8) == 0xff) { | |
261 | 20 | fixed(8, ff_byte, 0xff); | |
262 | 20 | payload_type += 255; | |
263 | } | ||
264 | 4850 | xu(8, last_payload_type_byte, tmp, 0, 254, 0); | |
265 | 4850 | payload_type += tmp; | |
266 | |||
267 | 4869 | while (show_bits(rw, 8) == 0xff) { | |
268 | 19 | fixed(8, ff_byte, 0xff); | |
269 | 19 | payload_size += 255; | |
270 | } | ||
271 | 4850 | xu(8, last_payload_size_byte, tmp, 0, 254, 0); | |
272 | 4850 | payload_size += tmp; | |
273 | |||
274 | // There must be space remaining for both the payload and | ||
275 | // the trailing bits on the SEI NAL unit. | ||
276 | 4850 | if (payload_size + 1 > get_bits_left(rw) / 8) { | |
277 | ✗ | av_log(ctx->log_ctx, AV_LOG_ERROR, | |
278 | "Invalid SEI message: payload_size too large " | ||
279 | "(%"PRIu32" bytes).\n", payload_size); | ||
280 | ✗ | return AVERROR_INVALIDDATA; | |
281 | } | ||
282 | 4850 | CHECK(init_get_bits(&payload_gbc, rw->buffer, | |
283 | get_bits_count(rw) + 8 * payload_size)); | ||
284 | 4850 | skip_bits_long(&payload_gbc, get_bits_count(rw)); | |
285 | |||
286 | 4850 | CHECK(ff_cbs_sei_list_add(current)); | |
287 | 4850 | message = ¤t->messages[k]; | |
288 | |||
289 | 4850 | message->payload_type = payload_type; | |
290 | 4850 | message->payload_size = payload_size; | |
291 | |||
292 | 4850 | CHECK(FUNC(message)(ctx, &payload_gbc, message)); | |
293 | |||
294 | 4850 | skip_bits_long(rw, 8 * payload_size); | |
295 | |||
296 | 4850 | if (!cbs_h2645_read_more_rbsp_data(rw)) | |
297 | 4830 | break; | |
298 | } | ||
299 | #else | ||
300 | 8534 | for (k = 0; k < current->nb_messages; k++) { | |
301 | PutBitContext start_state; | ||
302 | uint32_t tmp; | ||
303 | int trace, i; | ||
304 | |||
305 | 4277 | message = ¤t->messages[k]; | |
306 | |||
307 | // We write the payload twice in order to find the size. Trace | ||
308 | // output is switched off for the first write. | ||
309 | 4277 | trace = ctx->trace_enable; | |
310 | 4277 | ctx->trace_enable = 0; | |
311 | |||
312 | 4277 | start_state = *rw; | |
313 | 12831 | for (i = 0; i < 2; i++) { | |
314 | 8554 | *rw = start_state; | |
315 | |||
316 | 8554 | tmp = message->payload_type; | |
317 | 8594 | while (tmp >= 255) { | |
318 | 40 | fixed(8, ff_byte, 0xff); | |
319 | 40 | tmp -= 255; | |
320 | } | ||
321 | 8554 | xu(8, last_payload_type_byte, tmp, 0, 254, 0); | |
322 | |||
323 | 8554 | tmp = message->payload_size; | |
324 | 8592 | while (tmp >= 255) { | |
325 | 38 | fixed(8, ff_byte, 0xff); | |
326 | 38 | tmp -= 255; | |
327 | } | ||
328 | 8554 | xu(8, last_payload_size_byte, tmp, 0, 254, 0); | |
329 | |||
330 | 8554 | err = FUNC(message)(ctx, rw, message); | |
331 | 8554 | ctx->trace_enable = trace; | |
332 | 8554 | if (err < 0) | |
333 | ✗ | return err; | |
334 | } | ||
335 | } | ||
336 | #endif | ||
337 | |||
338 | 9087 | return 0; | |
339 | } | ||
340 |