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 | ✗ | SEI_FUNC(filler_payload, (CodedBitstreamContext *ctx, RWContext *rw, | |
20 | SEIRawFillerPayload *current, | ||
21 | 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 | 300 | SEI_FUNC(user_data_registered, (CodedBitstreamContext *ctx, RWContext *rw, | |
38 | SEIRawUserDataRegistered *current, | ||
39 | 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 | 240 | SEI_FUNC(user_data_unregistered, (CodedBitstreamContext *ctx, RWContext *rw, | |
70 | SEIRawUserDataUnregistered *current, | ||
71 | 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 | ✗ | SEI_FUNC(frame_packing_arrangement, (CodedBitstreamContext *ctx, RWContext *rw, | |
98 | SEIRawFramePackingArrangement *current, | ||
99 | SEIMessageState *unused)) | ||
100 | { | ||
101 | int err; | ||
102 | |||
103 | ✗ | HEADER("Frame Packing Arrangement"); | |
104 | |||
105 | ✗ | ue(fp_arrangement_id, 0, MAX_UINT_BITS(31)); | |
106 | ✗ | flag(fp_arrangement_cancel_flag); | |
107 | ✗ | if (!current->fp_arrangement_cancel_flag) { | |
108 | ✗ | u(7, fp_arrangement_type, 3, 5); | |
109 | ✗ | flag(fp_quincunx_sampling_flag); | |
110 | ✗ | u(6, fp_content_interpretation_type, 0, 2); | |
111 | ✗ | flag(fp_spatial_flipping_flag); | |
112 | ✗ | flag(fp_frame0_flipped_flag); | |
113 | ✗ | flag(fp_field_views_flag); | |
114 | ✗ | flag(fp_current_frame_is_frame0_flag); | |
115 | ✗ | flag(fp_frame0_self_contained_flag); | |
116 | ✗ | flag(fp_frame1_self_contained_flag); | |
117 | ✗ | if (!current->fp_quincunx_sampling_flag && current->fp_arrangement_type != 5) { | |
118 | ✗ | ub(4, fp_frame0_grid_position_x); | |
119 | ✗ | ub(4, fp_frame0_grid_position_y); | |
120 | ✗ | ub(4, fp_frame1_grid_position_x); | |
121 | ✗ | ub(4, fp_frame1_grid_position_y); | |
122 | } | ||
123 | ✗ | fixed(8, fp_arrangement_reserved_byte, 0); | |
124 | ✗ | flag(fp_arrangement_persistence_flag); | |
125 | } | ||
126 | ✗ | flag(fp_upsampled_aspect_ratio_flag); | |
127 | |||
128 | ✗ | return 0; | |
129 | } | ||
130 | |||
131 | 29140 | SEI_FUNC(decoded_picture_hash, (CodedBitstreamContext *ctx, | |
132 | RWContext *rw, | ||
133 | SEIRawDecodedPictureHash *current, | ||
134 | SEIMessageState *unused)) | ||
135 | { | ||
136 | int err, c_idx, i; | ||
137 | |||
138 | 14570 | HEADER("Decoded Picture Hash"); | |
139 | |||
140 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 7285 times.
|
14570 | u(8, dph_sei_hash_type, 0, 2); |
141 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 7285 times.
|
14570 | flag(dph_sei_single_component_flag); |
142 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 7285 times.
|
14570 | ub(7, dph_sei_reserved_zero_7bits); |
143 | |||
144 |
4/4✓ Branch 0 taken 516 times.
✓ Branch 1 taken 28108 times.
✓ Branch 2 taken 21339 times.
✓ Branch 3 taken 7285 times.
|
57248 | for (c_idx = 0; c_idx < (current->dph_sei_single_component_flag ? 1 : 3); |
145 | 42678 | c_idx++) { | |
146 |
1/2✓ Branch 0 taken 21339 times.
✗ Branch 1 not taken.
|
42678 | if (current->dph_sei_hash_type == 0) { |
147 |
2/2✓ Branch 0 taken 341424 times.
✓ Branch 1 taken 21339 times.
|
725526 | for (i = 0; i < 16; i++) |
148 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 341424 times.
|
682848 | us(8, dph_sei_picture_md5[c_idx][i], 0x00, 0xff, 2, c_idx, i); |
149 | ✗ | } else if (current->dph_sei_hash_type == 1) { | |
150 | ✗ | us(16, dph_sei_picture_crc[c_idx], 0x0000, 0xffff, 1, c_idx); | |
151 | ✗ | } else if (current->dph_sei_hash_type == 2) { | |
152 | ✗ | us(32, dph_sei_picture_checksum[c_idx], 0x00000000, 0xffffffff, 1, | |
153 | c_idx); | ||
154 | } | ||
155 | } | ||
156 | 14570 | return 0; | |
157 | } | ||
158 | |||
159 | 12 | SEI_FUNC(mastering_display_colour_volume, | |
160 | (CodedBitstreamContext *ctx, RWContext *rw, | ||
161 | SEIRawMasteringDisplayColourVolume *current, | ||
162 | SEIMessageState *state)) | ||
163 | { | ||
164 | int err, c; | ||
165 | |||
166 | 6 | HEADER("Mastering Display Colour Volume"); | |
167 | |||
168 |
2/2✓ Branch 0 taken 9 times.
✓ Branch 1 taken 3 times.
|
24 | for (c = 0; c < 3; c++) { |
169 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
|
18 | ubs(16, display_primaries_x[c], 1, c); |
170 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
|
18 | ubs(16, display_primaries_y[c], 1, c); |
171 | } | ||
172 | |||
173 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
|
6 | ub(16, white_point_x); |
174 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
|
6 | ub(16, white_point_y); |
175 | |||
176 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
|
6 | ub(32, max_display_mastering_luminance); |
177 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
|
6 | ub(32, min_display_mastering_luminance); |
178 | |||
179 | 6 | return 0; | |
180 | } | ||
181 | |||
182 | ✗ | SEI_FUNC(content_light_level_info, (CodedBitstreamContext *ctx, RWContext *rw, | |
183 | SEIRawContentLightLevelInfo *current, | ||
184 | SEIMessageState *state)) | ||
185 | { | ||
186 | int err; | ||
187 | |||
188 | ✗ | HEADER("Content Light Level Information"); | |
189 | |||
190 | ✗ | ub(16, max_content_light_level); | |
191 | ✗ | ub(16, max_pic_average_light_level); | |
192 | |||
193 | ✗ | return 0; | |
194 | } | ||
195 | |||
196 | ✗ | SEI_FUNC(alternative_transfer_characteristics, | |
197 | (CodedBitstreamContext *ctx, RWContext *rw, | ||
198 | SEIRawAlternativeTransferCharacteristics *current, | ||
199 | SEIMessageState *state)) | ||
200 | { | ||
201 | int err; | ||
202 | |||
203 | ✗ | HEADER("Alternative Transfer Characteristics"); | |
204 | |||
205 | ✗ | ub(8, preferred_transfer_characteristics); | |
206 | |||
207 | ✗ | return 0; | |
208 | } | ||
209 | |||
210 | ✗ | SEI_FUNC(ambient_viewing_environment, | |
211 | (CodedBitstreamContext *ctx, RWContext *rw, | ||
212 | SEIRawAmbientViewingEnvironment *current, | ||
213 | SEIMessageState *state)) | ||
214 | { | ||
215 | static const uint16_t max_ambient_light_value = 50000; | ||
216 | int err; | ||
217 | |||
218 | ✗ | HEADER("Ambient Viewing Environment"); | |
219 | |||
220 | ✗ | u(32, ambient_illuminance, 1, MAX_UINT_BITS(32)); | |
221 | ✗ | u(16, ambient_light_x, 0, max_ambient_light_value); | |
222 | ✗ | u(16, ambient_light_y, 0, max_ambient_light_value); | |
223 | |||
224 | ✗ | return 0; | |
225 | } | ||
226 | |||
227 | 28746 | static int FUNC(message)(CodedBitstreamContext *ctx, RWContext *rw, | |
228 | SEIRawMessage *current) | ||
229 | { | ||
230 | const SEIMessageTypeDescriptor *desc; | ||
231 | int err, i; | ||
232 | |||
233 | 28746 | desc = ff_cbs_sei_find_type(ctx, current->payload_type); | |
234 |
2/2✓ Branch 0 taken 14104 times.
✓ Branch 1 taken 269 times.
|
28746 | if (desc) { |
235 | 28208 | SEIMessageState state = { | |
236 | 28208 | .payload_type = current->payload_type, | |
237 | 28208 | .payload_size = current->payload_size, | |
238 | 28208 | .extension_present = current->extension_bit_length > 0, | |
239 | }; | ||
240 | int start_position, current_position, bits_written; | ||
241 | |||
242 | #ifdef READ | ||
243 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 5684 times.
|
11368 | CHECK(ff_cbs_sei_alloc_message_payload(current, desc)); |
244 | #endif | ||
245 | |||
246 | 28208 | start_position = bit_position(rw); | |
247 | |||
248 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 14104 times.
|
28208 | CHECK(desc->READWRITE(ctx, rw, current->payload, &state)); |
249 | |||
250 | 28208 | current_position = bit_position(rw); | |
251 | 28208 | bits_written = current_position - start_position; | |
252 | |||
253 |
3/4✓ Branch 1 taken 11821 times.
✓ Branch 2 taken 2283 times.
✓ Branch 3 taken 11821 times.
✗ Branch 4 not taken.
|
28208 | if (byte_alignment(rw) || state.extension_present || |
254 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 11821 times.
|
23642 | bits_written < 8 * current->payload_size) { |
255 | size_t bits_left; | ||
256 | |||
257 | #ifdef READ | ||
258 | 2066 | GetBitContext tmp = *rw; | |
259 | int trailing_bits, trailing_zero_bits; | ||
260 | |||
261 | 2066 | bits_left = 8 * current->payload_size - bits_written; | |
262 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1033 times.
|
2066 | if (bits_left > 8) |
263 | ✗ | skip_bits_long(&tmp, bits_left - 8); | |
264 | 2066 | trailing_bits = get_bits(&tmp, FFMIN(bits_left, 8)); | |
265 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1033 times.
|
2066 | if (trailing_bits == 0) { |
266 | // The trailing bits must contain a bit_equal_to_one, so | ||
267 | // they can't all be zero. | ||
268 | ✗ | return AVERROR_INVALIDDATA; | |
269 | } | ||
270 | 2066 | trailing_zero_bits = ff_ctz(trailing_bits); | |
271 | 2066 | current->extension_bit_length = | |
272 | 2066 | bits_left - 1 - trailing_zero_bits; | |
273 | #endif | ||
274 | |||
275 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2283 times.
|
4566 | if (current->extension_bit_length > 0) { |
276 | ✗ | allocate(current->extension_data, | |
277 | (current->extension_bit_length + 7) / 8); | ||
278 | |||
279 | ✗ | bits_left = current->extension_bit_length; | |
280 | ✗ | for (i = 0; bits_left > 0; i++) { | |
281 | ✗ | int length = FFMIN(bits_left, 8); | |
282 | ✗ | xu(length, reserved_payload_extension_data, | |
283 | current->extension_data[i], | ||
284 | 0, MAX_UINT_BITS(length), 0); | ||
285 | ✗ | bits_left -= length; | |
286 | } | ||
287 | } | ||
288 | |||
289 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2283 times.
|
4566 | fixed(1, bit_equal_to_one, 1); |
290 |
2/2✓ Branch 1 taken 3102 times.
✓ Branch 2 taken 2283 times.
|
10770 | while (byte_alignment(rw)) |
291 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 3102 times.
|
6204 | fixed(1, bit_equal_to_zero, 0); |
292 | } | ||
293 | |||
294 | #ifdef WRITE | ||
295 | 16840 | current->payload_size = (put_bits_count(rw) - start_position) / 8; | |
296 | #endif | ||
297 | } else { | ||
298 | uint8_t *data; | ||
299 | |||
300 | #ifdef READ | ||
301 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 135 times.
|
270 | allocate(current->payload_ref, current->payload_size); |
302 | 270 | current->payload = current->payload_ref; | |
303 | #else | ||
304 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 134 times.
|
268 | allocate(current->payload, current->payload_size); |
305 | #endif | ||
306 | 538 | data = current->payload; | |
307 | |||
308 |
2/2✓ Branch 0 taken 6370 times.
✓ Branch 1 taken 269 times.
|
13278 | for (i = 0; i < current->payload_size; i++) |
309 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 6370 times.
|
12740 | xu(8, payload_byte[i], data[i], 0, 255, 1, i); |
310 | } | ||
311 | |||
312 | 28746 | return 0; | |
313 | } | ||
314 | |||
315 | 10056 | static int FUNC(message_list)(CodedBitstreamContext *ctx, RWContext *rw, | |
316 | SEIRawMessageList *current, int prefix) | ||
317 | { | ||
318 | SEIRawMessage *message; | ||
319 | int err, k; | ||
320 | |||
321 | #ifdef READ | ||
322 | 5819 | for (k = 0;; k++) { | |
323 | 5819 | uint32_t payload_type = 0; | |
324 | 5819 | uint32_t payload_size = 0; | |
325 | uint32_t tmp; | ||
326 | GetBitContext payload_gbc; | ||
327 | |||
328 | 5839 | while (show_bits(rw, 8) == 0xff) { | |
329 | 20 | fixed(8, ff_byte, 0xff); | |
330 | 20 | payload_type += 255; | |
331 | } | ||
332 | 5819 | xu(8, last_payload_type_byte, tmp, 0, 254, 0); | |
333 | 5819 | payload_type += tmp; | |
334 | |||
335 | 5838 | while (show_bits(rw, 8) == 0xff) { | |
336 | 19 | fixed(8, ff_byte, 0xff); | |
337 | 19 | payload_size += 255; | |
338 | } | ||
339 | 5819 | xu(8, last_payload_size_byte, tmp, 0, 254, 0); | |
340 | 5819 | payload_size += tmp; | |
341 | |||
342 | // There must be space remaining for both the payload and | ||
343 | // the trailing bits on the SEI NAL unit. | ||
344 | 5819 | if (payload_size + 1 > get_bits_left(rw) / 8) { | |
345 | ✗ | av_log(ctx->log_ctx, AV_LOG_ERROR, | |
346 | "Invalid SEI message: payload_size too large " | ||
347 | "(%"PRIu32" bytes).\n", payload_size); | ||
348 | ✗ | return AVERROR_INVALIDDATA; | |
349 | } | ||
350 | 5819 | CHECK(init_get_bits(&payload_gbc, rw->buffer, | |
351 | get_bits_count(rw) + 8 * payload_size)); | ||
352 | 5819 | skip_bits_long(&payload_gbc, get_bits_count(rw)); | |
353 | |||
354 | 5819 | CHECK(ff_cbs_sei_list_add(current)); | |
355 | 5819 | message = ¤t->messages[k]; | |
356 | |||
357 | 5819 | message->payload_type = payload_type; | |
358 | 5819 | message->payload_size = payload_size; | |
359 | |||
360 | 5819 | CHECK(FUNC(message)(ctx, &payload_gbc, message)); | |
361 | |||
362 | 5819 | skip_bits_long(rw, 8 * payload_size); | |
363 | |||
364 | 5819 | if (!cbs_h2645_read_more_rbsp_data(rw)) | |
365 | 5799 | break; | |
366 | } | ||
367 | #else | ||
368 | 8534 | for (k = 0; k < current->nb_messages; k++) { | |
369 | PutBitContext start_state; | ||
370 | uint32_t tmp; | ||
371 | int trace, i; | ||
372 | |||
373 | 4277 | message = ¤t->messages[k]; | |
374 | |||
375 | // We write the payload twice in order to find the size. Trace | ||
376 | // output is switched off for the first write. | ||
377 | 4277 | trace = ctx->trace_enable; | |
378 | 4277 | ctx->trace_enable = 0; | |
379 | |||
380 | 4277 | start_state = *rw; | |
381 | 12831 | for (i = 0; i < 2; i++) { | |
382 | 8554 | *rw = start_state; | |
383 | |||
384 | 8554 | tmp = message->payload_type; | |
385 | 8594 | while (tmp >= 255) { | |
386 | 40 | fixed(8, ff_byte, 0xff); | |
387 | 40 | tmp -= 255; | |
388 | } | ||
389 | 8554 | xu(8, last_payload_type_byte, tmp, 0, 254, 0); | |
390 | |||
391 | 8554 | tmp = message->payload_size; | |
392 | 8592 | while (tmp >= 255) { | |
393 | 38 | fixed(8, ff_byte, 0xff); | |
394 | 38 | tmp -= 255; | |
395 | } | ||
396 | 8554 | xu(8, last_payload_size_byte, tmp, 0, 254, 0); | |
397 | |||
398 | 8554 | err = FUNC(message)(ctx, rw, message); | |
399 | 8554 | ctx->trace_enable = trace; | |
400 | 8554 | if (err < 0) | |
401 | ✗ | return err; | |
402 | } | ||
403 | } | ||
404 | #endif | ||
405 | |||
406 | 10056 | return 0; | |
407 | } | ||
408 |