FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/cbs_h265.c
Date: 2026-09-23 01:51:16
Exec Total Coverage
Lines: 159 235 67.7%
Functions: 10 10 100.0%
Branches: 85 153 55.6%

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 "libavutil/mem.h"
20 #include "libavutil/refstruct.h"
21 #include "bytestream.h"
22 #include "cbs.h"
23 #include "cbs_internal.h"
24 #include "cbs_h2645.h"
25 #include "cbs_h265.h"
26 #include "cbs_sei.h"
27 #include "get_bits.h"
28
29 #define HEADER(name) do { \
30 ff_cbs_trace_header(ctx, name); \
31 } while (0)
32
33 #define CHECK(call) do { \
34 err = (call); \
35 if (err < 0) \
36 return err; \
37 } while (0)
38
39 #define FUNC_NAME2(rw, codec, name) cbs_ ## codec ## _ ## rw ## _ ## name
40 #define FUNC_NAME1(rw, codec, name) FUNC_NAME2(rw, codec, name)
41 #define FUNC_H265(name) FUNC_NAME1(READWRITE, h265, name)
42 #define FUNC_NAME2_EXPORT(rw, codec, name) ff_cbs_ ## codec ## _ ## rw ## _ ## name
43 #define FUNC_NAME1_EXPORT(rw, codec, name) FUNC_NAME2_EXPORT(rw, codec, name)
44 #define FUNC_SEI(name) FUNC_NAME1_EXPORT(READWRITE, sei, name)
45
46 #define SEI_FUNC(name, args) \
47 static int FUNC_H265(name) args; \
48 static int FUNC_H265(name ## _internal)(CodedBitstreamContext *ctx, \
49 RWContext *rw, void *cur, \
50 SEIMessageState *state) \
51 { \
52 return FUNC_H265(name)(ctx, rw, cur, state); \
53 } \
54 static int FUNC_H265(name) args
55
56 #define SUBSCRIPTS(subs, ...) (subs > 0 ? ((int[subs + 1]){ subs, __VA_ARGS__ }) : NULL)
57
58 #define u(width, name, range_min, range_max) \
59 xu(width, name, current->name, range_min, range_max, 0, )
60 #define flag(name) ub(1, name)
61 #define ue(name, range_min, range_max) \
62 xue(name, current->name, range_min, range_max, 0, )
63 #define i(width, name, range_min, range_max) \
64 xi(width, name, current->name, range_min, range_max, 0, )
65 #define ib(width, name) \
66 xi(width, name, current->name, MIN_INT_BITS(width), MAX_INT_BITS(width), 0, )
67 #define se(name, range_min, range_max) \
68 xse(name, current->name, range_min, range_max, 0, )
69
70 #define us(width, name, range_min, range_max, subs, ...) \
71 xu(width, name, current->name, range_min, range_max, subs, __VA_ARGS__)
72 #define ubs(width, name, subs, ...) \
73 xu(width, name, current->name, 0, MAX_UINT_BITS(width), subs, __VA_ARGS__)
74 #define flags(name, subs, ...) \
75 xu(1, name, current->name, 0, 1, subs, __VA_ARGS__)
76 #define ues(name, range_min, range_max, subs, ...) \
77 xue(name, current->name, range_min, range_max, subs, __VA_ARGS__)
78 #define is(width, name, range_min, range_max, subs, ...) \
79 xi(width, name, current->name, range_min, range_max, subs, __VA_ARGS__)
80 #define ibs(width, name, subs, ...) \
81 xi(width, name, current->name, MIN_INT_BITS(width), MAX_INT_BITS(width), subs, __VA_ARGS__)
82 #define ses(name, range_min, range_max, subs, ...) \
83 xse(name, current->name, range_min, range_max, subs, __VA_ARGS__)
84
85 #define fixed(width, name, value) do { \
86 av_unused uint32_t fixed_value = value; \
87 xu(width, name, fixed_value, value, value, 0, ); \
88 } while (0)
89
90
91 #define READ
92 #define READWRITE read
93 #define RWContext GetBitContext
94
95 #define ub(width, name) do { \
96 uint32_t value; \
97 CHECK(ff_cbs_read_simple_unsigned(ctx, rw, width, #name, \
98 &value)); \
99 current->name = value; \
100 } while (0)
101 #define xu(width, name, var, range_min, range_max, subs, ...) do { \
102 uint32_t value; \
103 CHECK(ff_cbs_read_unsigned(ctx, rw, width, #name, \
104 SUBSCRIPTS(subs, __VA_ARGS__), \
105 &value, range_min, range_max)); \
106 var = value; \
107 } while (0)
108 #define xue(name, var, range_min, range_max, subs, ...) do { \
109 uint32_t value; \
110 CHECK(ff_cbs_read_ue_golomb(ctx, rw, #name, \
111 SUBSCRIPTS(subs, __VA_ARGS__), \
112 &value, range_min, range_max)); \
113 var = value; \
114 } while (0)
115 #define xi(width, name, var, range_min, range_max, subs, ...) do { \
116 int32_t value; \
117 CHECK(ff_cbs_read_signed(ctx, rw, width, #name, \
118 SUBSCRIPTS(subs, __VA_ARGS__), \
119 &value, range_min, range_max)); \
120 var = value; \
121 } while (0)
122 #define xse(name, var, range_min, range_max, subs, ...) do { \
123 int32_t value; \
124 CHECK(ff_cbs_read_se_golomb(ctx, rw, #name, \
125 SUBSCRIPTS(subs, __VA_ARGS__), \
126 &value, range_min, range_max)); \
127 var = value; \
128 } while (0)
129
130
131 #define infer(name, value) do { \
132 current->name = value; \
133 } while (0)
134
135 #define more_rbsp_data(var) ((var) = ff_cbs_h2645_read_more_rbsp_data(rw))
136
137 #define bit_position(rw) (get_bits_count(rw))
138 #define byte_alignment(rw) (get_bits_count(rw) % 8)
139
140 #define allocate(name, size) do { \
141 name ## _ref = av_buffer_allocz(size + \
142 AV_INPUT_BUFFER_PADDING_SIZE); \
143 if (!name ## _ref) \
144 return AVERROR(ENOMEM); \
145 name = (void *)name ## _ref->data; \
146 } while (0)
147
148 #define FUNC(name) FUNC_H265(name)
149 #include "cbs_h265_syntax_template.c"
150 #undef FUNC
151
152
153 #undef READ
154 #undef READWRITE
155 #undef RWContext
156 #undef ub
157 #undef xu
158 #undef xi
159 #undef xue
160 #undef xse
161 #undef infer
162 #undef more_rbsp_data
163 #undef bit_position
164 #undef byte_alignment
165 #undef allocate
166 #undef allocate_struct
167
168
169 #define WRITE
170 #define READWRITE write
171 #define RWContext PutBitContext
172
173 #define ub(width, name) do { \
174 uint32_t value = current->name; \
175 CHECK(ff_cbs_write_simple_unsigned(ctx, rw, width, #name, \
176 value)); \
177 } while (0)
178 #define xu(width, name, var, range_min, range_max, subs, ...) do { \
179 uint32_t value = var; \
180 CHECK(ff_cbs_write_unsigned(ctx, rw, width, #name, \
181 SUBSCRIPTS(subs, __VA_ARGS__), \
182 value, range_min, range_max)); \
183 } while (0)
184 #define xue(name, var, range_min, range_max, subs, ...) do { \
185 uint32_t value = var; \
186 CHECK(ff_cbs_write_ue_golomb(ctx, rw, #name, \
187 SUBSCRIPTS(subs, __VA_ARGS__), \
188 value, range_min, range_max)); \
189 } while (0)
190 #define xi(width, name, var, range_min, range_max, subs, ...) do { \
191 int32_t value = var; \
192 CHECK(ff_cbs_write_signed(ctx, rw, width, #name, \
193 SUBSCRIPTS(subs, __VA_ARGS__), \
194 value, range_min, range_max)); \
195 } while (0)
196 #define xse(name, var, range_min, range_max, subs, ...) do { \
197 int32_t value = var; \
198 CHECK(ff_cbs_write_se_golomb(ctx, rw, #name, \
199 SUBSCRIPTS(subs, __VA_ARGS__), \
200 value, range_min, range_max)); \
201 } while (0)
202
203 #define infer(name, value) do { \
204 if (current->name != (value)) { \
205 av_log(ctx->log_ctx, AV_LOG_ERROR, \
206 "%s does not match inferred value: " \
207 "%"PRId64", but should be %"PRId64".\n", \
208 #name, (int64_t)current->name, (int64_t)(value)); \
209 return AVERROR_INVALIDDATA; \
210 } \
211 } while (0)
212
213 #define more_rbsp_data(var) (var)
214
215 #define bit_position(rw) (put_bits_count(rw))
216 #define byte_alignment(rw) (put_bits_count(rw) % 8)
217
218 #define allocate(name, size) do { \
219 if (!name) { \
220 av_log(ctx->log_ctx, AV_LOG_ERROR, "%s must be set " \
221 "for writing.\n", #name); \
222 return AVERROR_INVALIDDATA; \
223 } \
224 } while (0)
225
226 #define FUNC(name) FUNC_H265(name)
227 #include "cbs_h265_syntax_template.c"
228 #undef FUNC
229
230 #undef WRITE
231 #undef READWRITE
232 #undef RWContext
233 #undef ub
234 #undef xu
235 #undef xi
236 #undef xue
237 #undef xse
238 #undef u
239 #undef i
240 #undef flag
241 #undef ue
242 #undef se
243 #undef infer
244 #undef more_rbsp_data
245 #undef bit_position
246 #undef byte_alignment
247 #undef allocate
248
249
250
251 2650 static int cbs_h265_split_fragment(CodedBitstreamContext *ctx,
252 CodedBitstreamFragment *frag,
253 int header)
254 {
255 2650 enum AVCodecID codec_id = ctx->codec->codec_id;
256 2650 CodedBitstreamH265Context *priv = ctx->priv_data;
257 2650 CodedBitstreamH2645Context *h2645 = &priv->common;
258 GetByteContext gbc;
259 int err;
260
261
2/4
✓ Branch 0 taken 2650 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2650 times.
2650 av_assert0(frag->data && frag->nb_units == 0);
262
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2650 times.
2650 if (frag->data_size == 0)
263 return 0;
264
265
3/4
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 2620 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 30 times.
2650 if (header && frag->data[0]) {
266 // HVCC header.
267 size_t size, start, end;
268 int i, j, nb_arrays, nal_unit_type, nb_nals, version;
269
270 h2645->mp4 = 1;
271
272 bytestream2_init(&gbc, frag->data, frag->data_size);
273
274 if (bytestream2_get_bytes_left(&gbc) < 23)
275 return AVERROR_INVALIDDATA;
276
277 version = bytestream2_get_byte(&gbc);
278 if (version != 1) {
279 av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid HVCC header: "
280 "first byte %u.\n", version);
281 return AVERROR_INVALIDDATA;
282 }
283
284 bytestream2_skip(&gbc, 20);
285 h2645->nal_length_size = (bytestream2_get_byte(&gbc) & 3) + 1;
286
287 nb_arrays = bytestream2_get_byte(&gbc);
288 for (i = 0; i < nb_arrays; i++) {
289 nal_unit_type = bytestream2_get_byte(&gbc) & 0x3f;
290 nb_nals = bytestream2_get_be16(&gbc);
291
292 start = bytestream2_tell(&gbc);
293 for (j = 0; j < nb_nals; j++) {
294 if (bytestream2_get_bytes_left(&gbc) < 2)
295 return AVERROR_INVALIDDATA;
296 size = bytestream2_get_be16(&gbc);
297 if (bytestream2_get_bytes_left(&gbc) < size)
298 return AVERROR_INVALIDDATA;
299 bytestream2_skip(&gbc, size);
300 }
301 end = bytestream2_tell(&gbc);
302
303 err = ff_h2645_packet_split(&h2645->read_packet,
304 frag->data + start, end - start,
305 ctx->log_ctx, 2, AV_CODEC_ID_HEVC,
306 H2645_FLAG_IS_NALFF | H2645_FLAG_SMALL_PADDING | H2645_FLAG_USE_REF);
307 if (err < 0) {
308 av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to split "
309 "HVCC array %d (%d NAL units of type %d).\n",
310 i, nb_nals, nal_unit_type);
311 return err;
312 }
313 err = ff_cbs_h2645_fragment_add_nals(ctx, frag, &h2645->read_packet);
314 if (err < 0)
315 return err;
316 }
317 } else {
318
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2650 times.
2650 int flags = (H2645_FLAG_IS_NALFF * !!h2645->mp4) | H2645_FLAG_SMALL_PADDING | H2645_FLAG_USE_REF;
319 // Annex B, or later MP4 with already-known parameters.
320
321 2650 err = ff_h2645_packet_split(&h2645->read_packet,
322 2650 frag->data, frag->data_size,
323 ctx->log_ctx,
324 h2645->nal_length_size,
325 codec_id, flags);
326
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2650 times.
2650 if (err < 0)
327 return err;
328
329 2650 err = ff_cbs_h2645_fragment_add_nals(ctx, frag, &h2645->read_packet);
330
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2650 times.
2650 if (err < 0)
331 return err;
332 }
333
334 2650 return 0;
335 }
336
337 #define cbs_h2645_replace_ps(ps_name, ps_var, id_element) \
338 static int cbs_h265_replace_ ## ps_var(CodedBitstreamContext *ctx, \
339 CodedBitstreamUnit *unit) \
340 { \
341 CodedBitstreamH265Context *priv = ctx->priv_data; \
342 H265Raw## ps_name *ps_var = unit->content; \
343 unsigned int id = ps_var->id_element; \
344 int err = ff_cbs_make_unit_refcounted(ctx, unit); \
345 if (err < 0) \
346 return err; \
347 if (priv->ps_var[id] == priv->active_ ## ps_var) \
348 priv->active_ ## ps_var = NULL ; \
349 av_assert0(unit->content_ref); \
350 av_refstruct_replace(&priv->ps_var[id], unit->content_ref); \
351 return 0; \
352 }
353
354
3/6
✗ Branch 1 not taken.
✓ Branch 2 taken 132 times.
✓ Branch 3 taken 132 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 132 times.
132 cbs_h2645_replace_ps(VPS, vps, vps_video_parameter_set_id)
355
4/6
✗ Branch 1 not taken.
✓ Branch 2 taken 138 times.
✓ Branch 3 taken 135 times.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 138 times.
138 cbs_h2645_replace_ps(SPS, sps, sps_seq_parameter_set_id)
356
4/6
✗ Branch 1 not taken.
✓ Branch 2 taken 714 times.
✓ Branch 3 taken 461 times.
✓ Branch 4 taken 253 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 714 times.
714 cbs_h2645_replace_ps(PPS, pps, pps_pic_parameter_set_id)
357
358 9969 static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx,
359 CodedBitstreamUnit *unit)
360 {
361 GetBitContext gbc;
362 int err;
363
364 9969 err = init_get_bits(&gbc, unit->data, 8 * unit->data_size);
365
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9969 times.
9969 if (err < 0)
366 return err;
367
368 9969 err = ff_cbs_alloc_unit_content(ctx, unit);
369
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9969 times.
9969 if (err < 0)
370 return err;
371
372
6/8
✓ Branch 0 taken 69 times.
✓ Branch 1 taken 73 times.
✓ Branch 2 taken 424 times.
✓ Branch 3 taken 7484 times.
✓ Branch 4 taken 60 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1859 times.
✗ Branch 7 not taken.
9969 switch (unit->type) {
373 69 case HEVC_NAL_VPS:
374 {
375 69 H265RawVPS *vps = unit->content;
376
377 69 err = cbs_h265_read_vps(ctx, &gbc, vps);
378
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
69 if (err < 0)
379 return err;
380
381 69 err = cbs_h265_replace_vps(ctx, unit);
382
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
69 if (err < 0)
383 return err;
384 }
385 69 break;
386 73 case HEVC_NAL_SPS:
387 {
388 73 H265RawSPS *sps = unit->content;
389
390 73 err = cbs_h265_read_sps(ctx, &gbc, sps);
391
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 73 times.
73 if (err < 0)
392 return err;
393
394 73 err = cbs_h265_replace_sps(ctx, unit);
395
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 73 times.
73 if (err < 0)
396 return err;
397 }
398 73 break;
399
400 424 case HEVC_NAL_PPS:
401 {
402 424 H265RawPPS *pps = unit->content;
403
404 424 err = cbs_h265_read_pps(ctx, &gbc, pps);
405
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 424 times.
424 if (err < 0)
406 return err;
407
408 424 err = cbs_h265_replace_pps(ctx, unit);
409
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 424 times.
424 if (err < 0)
410 return err;
411 }
412 424 break;
413
414 7484 case HEVC_NAL_TRAIL_N:
415 case HEVC_NAL_TRAIL_R:
416 case HEVC_NAL_TSA_N:
417 case HEVC_NAL_TSA_R:
418 case HEVC_NAL_STSA_N:
419 case HEVC_NAL_STSA_R:
420 case HEVC_NAL_RADL_N:
421 case HEVC_NAL_RADL_R:
422 case HEVC_NAL_RASL_N:
423 case HEVC_NAL_RASL_R:
424 case HEVC_NAL_BLA_W_LP:
425 case HEVC_NAL_BLA_W_RADL:
426 case HEVC_NAL_BLA_N_LP:
427 case HEVC_NAL_IDR_W_RADL:
428 case HEVC_NAL_IDR_N_LP:
429 case HEVC_NAL_CRA_NUT:
430 {
431 7484 H265RawSlice *slice = unit->content;
432 int pos, len;
433
434 7484 err = cbs_h265_read_slice_segment_header(ctx, &gbc, &slice->header);
435
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7484 times.
7484 if (err < 0)
436 return err;
437
438
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7484 times.
7484 if (!ff_cbs_h2645_read_more_rbsp_data(&gbc))
439 return AVERROR_INVALIDDATA;
440
441 7484 pos = get_bits_count(&gbc);
442 7484 len = unit->data_size;
443
444 7484 slice->data_size = len - pos / 8;
445 7484 slice->data_ref = av_buffer_ref(unit->data_ref);
446
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7484 times.
7484 if (!slice->data_ref)
447 return AVERROR(ENOMEM);
448 7484 slice->data = unit->data + pos / 8;
449 7484 slice->data_bit_start = pos % 8;
450 }
451 7484 break;
452
453 60 case HEVC_NAL_AUD:
454 {
455 60 err = cbs_h265_read_aud(ctx, &gbc, unit->content);
456
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 60 times.
60 if (err < 0)
457 return err;
458 }
459 60 break;
460
461 case HEVC_NAL_FD_NUT:
462 {
463 err = cbs_h265_read_filler(ctx, &gbc, unit->content);
464 if (err < 0)
465 return err;
466 }
467 break;
468
469 1859 case HEVC_NAL_SEI_PREFIX:
470 case HEVC_NAL_SEI_SUFFIX:
471 {
472 1859 err = cbs_h265_read_sei(ctx, &gbc, unit->content,
473 1859 unit->type == HEVC_NAL_SEI_PREFIX);
474
475
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1859 times.
1859 if (err < 0)
476 return err;
477 }
478 1859 break;
479
480 default:
481 return AVERROR(ENOSYS);
482 }
483
484 9969 return 0;
485 }
486
487 8146 static int cbs_h265_write_nal_unit(CodedBitstreamContext *ctx,
488 CodedBitstreamUnit *unit,
489 PutBitContext *pbc)
490 {
491 int err;
492
493
6/8
✓ Branch 0 taken 63 times.
✓ Branch 1 taken 65 times.
✓ Branch 2 taken 290 times.
✓ Branch 3 taken 6104 times.
✓ Branch 4 taken 60 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1564 times.
✗ Branch 7 not taken.
8146 switch (unit->type) {
494 63 case HEVC_NAL_VPS:
495 {
496 63 H265RawVPS *vps = unit->content;
497
498 63 err = cbs_h265_write_vps(ctx, pbc, vps);
499
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 63 times.
63 if (err < 0)
500 return err;
501
502 63 err = cbs_h265_replace_vps(ctx, unit);
503
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 63 times.
63 if (err < 0)
504 return err;
505 }
506 63 break;
507
508 65 case HEVC_NAL_SPS:
509 {
510 65 H265RawSPS *sps = unit->content;
511
512 65 err = cbs_h265_write_sps(ctx, pbc, sps);
513
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 65 times.
65 if (err < 0)
514 return err;
515
516 65 err = cbs_h265_replace_sps(ctx, unit);
517
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 65 times.
65 if (err < 0)
518 return err;
519 }
520 65 break;
521
522 290 case HEVC_NAL_PPS:
523 {
524 290 H265RawPPS *pps = unit->content;
525
526 290 err = cbs_h265_write_pps(ctx, pbc, pps);
527
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 290 times.
290 if (err < 0)
528 return err;
529
530 290 err = cbs_h265_replace_pps(ctx, unit);
531
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 290 times.
290 if (err < 0)
532 return err;
533 }
534 290 break;
535
536 6104 case HEVC_NAL_TRAIL_N:
537 case HEVC_NAL_TRAIL_R:
538 case HEVC_NAL_TSA_N:
539 case HEVC_NAL_TSA_R:
540 case HEVC_NAL_STSA_N:
541 case HEVC_NAL_STSA_R:
542 case HEVC_NAL_RADL_N:
543 case HEVC_NAL_RADL_R:
544 case HEVC_NAL_RASL_N:
545 case HEVC_NAL_RASL_R:
546 case HEVC_NAL_BLA_W_LP:
547 case HEVC_NAL_BLA_W_RADL:
548 case HEVC_NAL_BLA_N_LP:
549 case HEVC_NAL_IDR_W_RADL:
550 case HEVC_NAL_IDR_N_LP:
551 case HEVC_NAL_CRA_NUT:
552 {
553 6104 H265RawSlice *slice = unit->content;
554
555 6104 err = cbs_h265_write_slice_segment_header(ctx, pbc, &slice->header);
556
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6104 times.
6104 if (err < 0)
557 return err;
558
559
1/2
✓ Branch 0 taken 6104 times.
✗ Branch 1 not taken.
6104 if (slice->data) {
560 6104 err = ff_cbs_h2645_write_slice_data(ctx, pbc, slice->data,
561 slice->data_size,
562 slice->data_bit_start);
563
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6104 times.
6104 if (err < 0)
564 return err;
565 } else {
566 // No slice data - that was just the header.
567 }
568 }
569 6104 break;
570
571 60 case HEVC_NAL_AUD:
572 {
573 60 err = cbs_h265_write_aud(ctx, pbc, unit->content);
574
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 60 times.
60 if (err < 0)
575 return err;
576 }
577 60 break;
578
579 case HEVC_NAL_FD_NUT:
580 {
581 err = cbs_h265_write_filler(ctx, pbc, unit->content);
582 if (err < 0)
583 return err;
584 }
585 break;
586
587 1564 case HEVC_NAL_SEI_PREFIX:
588 case HEVC_NAL_SEI_SUFFIX:
589 {
590 1564 err = cbs_h265_write_sei(ctx, pbc, unit->content,
591 1564 unit->type == HEVC_NAL_SEI_PREFIX);
592
593
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1564 times.
1564 if (err < 0)
594 return err;
595 }
596 1564 break;
597
598 default:
599 av_log(ctx->log_ctx, AV_LOG_ERROR, "Write unimplemented for "
600 "NAL unit type %"PRIu32".\n", unit->type);
601 return AVERROR_PATCHWELCOME;
602 }
603
604 8146 return 0;
605 }
606
607 536 static int cbs_h265_discarded_nal_unit(CodedBitstreamContext *ctx,
608 const CodedBitstreamUnit *unit,
609 enum AVDiscard skip)
610 {
611 H265RawSliceHeader *slice;
612
613
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 536 times.
536 if (skip <= AVDISCARD_DEFAULT)
614 return 0;
615
616
3/3
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 328 times.
✓ Branch 2 taken 204 times.
536 switch (unit->type) {
617 4 case HEVC_NAL_BLA_W_LP:
618 case HEVC_NAL_BLA_W_RADL:
619 case HEVC_NAL_BLA_N_LP:
620 case HEVC_NAL_IDR_W_RADL:
621 case HEVC_NAL_IDR_N_LP:
622 case HEVC_NAL_CRA_NUT:
623 // IRAP slice
624
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (skip < AVDISCARD_ALL)
625 4 return 0;
626 break;
627
628 328 case HEVC_NAL_TRAIL_R:
629 case HEVC_NAL_TRAIL_N:
630 case HEVC_NAL_TSA_N:
631 case HEVC_NAL_TSA_R:
632 case HEVC_NAL_STSA_N:
633 case HEVC_NAL_STSA_R:
634 case HEVC_NAL_RADL_N:
635 case HEVC_NAL_RADL_R:
636 case HEVC_NAL_RASL_N:
637 case HEVC_NAL_RASL_R:
638 // Slice
639 328 break;
640 204 default:
641 // Don't discard non-slice nal.
642 204 return 0;
643 }
644
645
2/2
✓ Branch 0 taken 47 times.
✓ Branch 1 taken 281 times.
328 if (skip >= AVDISCARD_NONKEY)
646 47 return 1;
647
648 281 slice = (H265RawSliceHeader *)unit->content;
649
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 281 times.
281 if (!slice) {
650 av_log(ctx->log_ctx, AV_LOG_WARNING,
651 "h265 slice header is null, missing decompose?\n");
652 return 0;
653 }
654
655
3/4
✓ Branch 0 taken 47 times.
✓ Branch 1 taken 234 times.
✓ Branch 2 taken 47 times.
✗ Branch 3 not taken.
281 if (skip >= AVDISCARD_NONINTRA && slice->slice_type != HEVC_SLICE_I)
656 47 return 1;
657
3/4
✓ Branch 0 taken 47 times.
✓ Branch 1 taken 187 times.
✓ Branch 2 taken 47 times.
✗ Branch 3 not taken.
234 if (skip >= AVDISCARD_BIDIR && slice->slice_type == HEVC_SLICE_B)
658 47 return 1;
659
660
1/2
✓ Branch 0 taken 187 times.
✗ Branch 1 not taken.
187 if (skip >= AVDISCARD_NONREF) {
661
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 163 times.
187 switch (unit->type) {
662 24 case HEVC_NAL_TRAIL_N:
663 case HEVC_NAL_TSA_N:
664 case HEVC_NAL_STSA_N:
665 case HEVC_NAL_RADL_N:
666 case HEVC_NAL_RASL_N:
667 case HEVC_NAL_VCL_N10:
668 case HEVC_NAL_VCL_N12:
669 case HEVC_NAL_VCL_N14:
670 // non-ref
671 24 return 1;
672 163 default:
673 163 break;
674 }
675 }
676
677 163 return 0;
678 }
679
680 3 static av_cold void cbs_h265_flush(CodedBitstreamContext *ctx)
681 {
682 3 CodedBitstreamH265Context *h265 = ctx->priv_data;
683
684
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 3 times.
51 for (int i = 0; i < FF_ARRAY_ELEMS(h265->vps); i++)
685 48 av_refstruct_unref(&h265->vps[i]);
686
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 3 times.
51 for (int i = 0; i < FF_ARRAY_ELEMS(h265->sps); i++)
687 48 av_refstruct_unref(&h265->sps[i]);
688
2/2
✓ Branch 0 taken 192 times.
✓ Branch 1 taken 3 times.
195 for (int i = 0; i < FF_ARRAY_ELEMS(h265->pps); i++)
689 192 av_refstruct_unref(&h265->pps[i]);
690
691 3 h265->active_vps = NULL;
692 3 h265->active_sps = NULL;
693 3 h265->active_pps = NULL;
694 3 }
695
696 53 static av_cold void cbs_h265_close(CodedBitstreamContext *ctx)
697 {
698 53 CodedBitstreamH265Context *h265 = ctx->priv_data;
699 int i;
700
701 53 ff_h2645_packet_uninit(&h265->common.read_packet);
702
703
2/2
✓ Branch 0 taken 848 times.
✓ Branch 1 taken 53 times.
901 for (i = 0; i < FF_ARRAY_ELEMS(h265->vps); i++)
704 848 av_refstruct_unref(&h265->vps[i]);
705
2/2
✓ Branch 0 taken 848 times.
✓ Branch 1 taken 53 times.
901 for (i = 0; i < FF_ARRAY_ELEMS(h265->sps); i++)
706 848 av_refstruct_unref(&h265->sps[i]);
707
2/2
✓ Branch 0 taken 3392 times.
✓ Branch 1 taken 53 times.
3445 for (i = 0; i < FF_ARRAY_ELEMS(h265->pps); i++)
708 3392 av_refstruct_unref(&h265->pps[i]);
709 53 }
710
711 1859 static void cbs_h265_free_sei(AVRefStructOpaque unused, void *content)
712 {
713 1859 H265RawSEI *sei = content;
714 1859 ff_cbs_sei_free_message_list(&sei->message_list);
715 1859 }
716
717 static CodedBitstreamUnitTypeDescriptor cbs_h265_unit_types[] = {
718 {
719 .nb_unit_types = 1,
720 .unit_type.list = { HEVC_NAL_VPS },
721 .content_type = CBS_CONTENT_TYPE_INTERNAL_REFS,
722 .content_size = sizeof(H265RawVPS),
723 .type.ref = {
724 .nb_offsets = 2,
725 .offsets = { offsetof(H265RawVPS, extension_data.data),
726 offsetof(H265RawVPS, hrd_parameters) }
727 },
728 },
729
730 CBS_UNIT_TYPE_INTERNAL_REF(HEVC_NAL_SPS, H265RawSPS, extension_data.data),
731 CBS_UNIT_TYPE_INTERNAL_REF(HEVC_NAL_PPS, H265RawPPS, extension_data.data),
732
733 CBS_UNIT_TYPE_POD(HEVC_NAL_AUD, H265RawAUD),
734 CBS_UNIT_TYPE_POD(HEVC_NAL_FD_NUT, H265RawFiller),
735
736 // Slices of non-IRAP pictures.
737 CBS_UNIT_RANGE_INTERNAL_REF(HEVC_NAL_TRAIL_N, HEVC_NAL_RASL_R,
738 H265RawSlice, data),
739 // Slices of IRAP pictures.
740 CBS_UNIT_RANGE_INTERNAL_REF(HEVC_NAL_BLA_W_LP, HEVC_NAL_CRA_NUT,
741 H265RawSlice, data),
742
743 CBS_UNIT_TYPES_COMPLEX((HEVC_NAL_SEI_PREFIX, HEVC_NAL_SEI_SUFFIX),
744 H265RawSEI, cbs_h265_free_sei),
745
746 CBS_UNIT_TYPE_END_OF_LIST
747 };
748
749 // Macro for the read/write pair.
750 #define SEI_MESSAGE_RW(codec, name) \
751 .read = cbs_ ## codec ## _read_ ## name ## _internal, \
752 .write = cbs_ ## codec ## _write_ ## name ## _internal
753
754 const SEIMessageTypeDescriptor ff_cbs_sei_h265_types[] = {
755 {
756 SEI_TYPE_BUFFERING_PERIOD,
757 1, 0,
758 sizeof(H265RawSEIBufferingPeriod),
759 SEI_MESSAGE_RW(h265, sei_buffering_period),
760 },
761 {
762 SEI_TYPE_PIC_TIMING,
763 1, 0,
764 sizeof(H265RawSEIPicTiming),
765 SEI_MESSAGE_RW(h265, sei_pic_timing),
766 },
767 {
768 SEI_TYPE_PAN_SCAN_RECT,
769 1, 0,
770 sizeof(H265RawSEIPanScanRect),
771 SEI_MESSAGE_RW(h265, sei_pan_scan_rect),
772 },
773 {
774 SEI_TYPE_RECOVERY_POINT,
775 1, 0,
776 sizeof(H265RawSEIRecoveryPoint),
777 SEI_MESSAGE_RW(h265, sei_recovery_point),
778 },
779 {
780 SEI_TYPE_FILM_GRAIN_CHARACTERISTICS,
781 1, 0,
782 sizeof(H265RawFilmGrainCharacteristics),
783 SEI_MESSAGE_RW(h265, film_grain_characteristics),
784 },
785 {
786 SEI_TYPE_DISPLAY_ORIENTATION,
787 1, 0,
788 sizeof(H265RawSEIDisplayOrientation),
789 SEI_MESSAGE_RW(h265, sei_display_orientation),
790 },
791 {
792 SEI_TYPE_ACTIVE_PARAMETER_SETS,
793 1, 0,
794 sizeof(H265RawSEIActiveParameterSets),
795 SEI_MESSAGE_RW(h265, sei_active_parameter_sets),
796 },
797 {
798 SEI_TYPE_DECODED_PICTURE_HASH,
799 0, 1,
800 sizeof(H265RawSEIDecodedPictureHash),
801 SEI_MESSAGE_RW(h265, sei_decoded_picture_hash),
802 },
803 {
804 SEI_TYPE_TIME_CODE,
805 1, 0,
806 sizeof(H265RawSEITimeCode),
807 SEI_MESSAGE_RW(h265, sei_time_code),
808 },
809 {
810 SEI_TYPE_ALPHA_CHANNEL_INFO,
811 1, 0,
812 sizeof(H265RawSEIAlphaChannelInfo),
813 SEI_MESSAGE_RW(h265, sei_alpha_channel_info),
814 },
815 {
816 SEI_TYPE_THREE_DIMENSIONAL_REFERENCE_DISPLAYS_INFO,
817 1, 0,
818 sizeof(H265RawSEI3DReferenceDisplaysInfo),
819 SEI_MESSAGE_RW(h265, sei_3d_reference_displays_info),
820 },
821 SEI_MESSAGE_TYPE_END
822 };
823
824 const CodedBitstreamType ff_cbs_type_h265 = {
825 .codec_id = AV_CODEC_ID_HEVC,
826
827 .priv_data_size = sizeof(CodedBitstreamH265Context),
828
829 .unit_types = cbs_h265_unit_types,
830
831 .split_fragment = &cbs_h265_split_fragment,
832 .read_unit = &cbs_h265_read_nal_unit,
833 .write_unit = &cbs_h265_write_nal_unit,
834 .discarded_unit = &cbs_h265_discarded_nal_unit,
835 .assemble_fragment = &ff_cbs_h2645_assemble_fragment,
836
837 .flush = &cbs_h265_flush,
838 .close = &cbs_h265_close,
839 };
840