FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/cbs_h265.c
Date: 2026-03-13 22:30:28
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 = 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 2651 static int cbs_h265_split_fragment(CodedBitstreamContext *ctx,
252 CodedBitstreamFragment *frag,
253 int header)
254 {
255 2651 enum AVCodecID codec_id = ctx->codec->codec_id;
256 2651 CodedBitstreamH265Context *priv = ctx->priv_data;
257 2651 CodedBitstreamH2645Context *h2645 = &priv->common;
258 GetByteContext gbc;
259 int err;
260
261
2/4
✓ Branch 0 taken 2651 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2651 times.
2651 av_assert0(frag->data && frag->nb_units == 0);
262
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2651 times.
2651 if (frag->data_size == 0)
263 return 0;
264
265
3/4
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 2622 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 29 times.
2651 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 2651 times.
2651 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 2651 err = ff_h2645_packet_split(&h2645->read_packet,
322 2651 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 2651 times.
2651 if (err < 0)
327 return err;
328
329 2651 err = ff_cbs_h2645_fragment_add_nals(ctx, frag, &h2645->read_packet);
330
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2651 times.
2651 if (err < 0)
331 return err;
332 }
333
334 2651 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 126 times.
✓ Branch 3 taken 126 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 126 times.
126 cbs_h2645_replace_ps(VPS, vps, vps_video_parameter_set_id)
355
4/6
✗ Branch 1 not taken.
✓ Branch 2 taken 132 times.
✓ Branch 3 taken 129 times.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 132 times.
132 cbs_h2645_replace_ps(SPS, sps, sps_seq_parameter_set_id)
356
4/6
✗ Branch 1 not taken.
✓ Branch 2 taken 708 times.
✓ Branch 3 taken 457 times.
✓ Branch 4 taken 251 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 708 times.
708 cbs_h2645_replace_ps(PPS, pps, pps_pic_parameter_set_id)
357
358 9960 static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx,
359 CodedBitstreamUnit *unit)
360 {
361 GetBitContext gbc;
362 int err;
363
364 9960 err = init_get_bits(&gbc, unit->data, 8 * unit->data_size);
365
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9960 times.
9960 if (err < 0)
366 return err;
367
368 9960 err = ff_cbs_alloc_unit_content(ctx, unit);
369
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9960 times.
9960 if (err < 0)
370 return err;
371
372
6/8
✓ Branch 0 taken 66 times.
✓ Branch 1 taken 70 times.
✓ Branch 2 taken 421 times.
✓ Branch 3 taken 7486 times.
✓ Branch 4 taken 60 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1857 times.
✗ Branch 7 not taken.
9960 switch (unit->type) {
373 66 case HEVC_NAL_VPS:
374 {
375 66 H265RawVPS *vps = unit->content;
376
377 66 err = cbs_h265_read_vps(ctx, &gbc, vps);
378
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66 times.
66 if (err < 0)
379 return err;
380
381 66 err = cbs_h265_replace_vps(ctx, unit);
382
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66 times.
66 if (err < 0)
383 return err;
384 }
385 66 break;
386 70 case HEVC_NAL_SPS:
387 {
388 70 H265RawSPS *sps = unit->content;
389
390 70 err = cbs_h265_read_sps(ctx, &gbc, sps);
391
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 70 times.
70 if (err < 0)
392 return err;
393
394 70 err = cbs_h265_replace_sps(ctx, unit);
395
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 70 times.
70 if (err < 0)
396 return err;
397 }
398 70 break;
399
400 421 case HEVC_NAL_PPS:
401 {
402 421 H265RawPPS *pps = unit->content;
403
404 421 err = cbs_h265_read_pps(ctx, &gbc, pps);
405
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 421 times.
421 if (err < 0)
406 return err;
407
408 421 err = cbs_h265_replace_pps(ctx, unit);
409
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 421 times.
421 if (err < 0)
410 return err;
411 }
412 421 break;
413
414 7486 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 7486 H265RawSlice *slice = unit->content;
432 int pos, len;
433
434 7486 err = cbs_h265_read_slice_segment_header(ctx, &gbc, &slice->header);
435
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7486 times.
7486 if (err < 0)
436 return err;
437
438
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7486 times.
7486 if (!ff_cbs_h2645_read_more_rbsp_data(&gbc))
439 return AVERROR_INVALIDDATA;
440
441 7486 pos = get_bits_count(&gbc);
442 7486 len = unit->data_size;
443
444 7486 slice->data_size = len - pos / 8;
445 7486 slice->data_ref = av_buffer_ref(unit->data_ref);
446
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7486 times.
7486 if (!slice->data_ref)
447 return AVERROR(ENOMEM);
448 7486 slice->data = unit->data + pos / 8;
449 7486 slice->data_bit_start = pos % 8;
450 }
451 7486 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 1857 case HEVC_NAL_SEI_PREFIX:
470 case HEVC_NAL_SEI_SUFFIX:
471 {
472 1857 err = cbs_h265_read_sei(ctx, &gbc, unit->content,
473 1857 unit->type == HEVC_NAL_SEI_PREFIX);
474
475
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1857 times.
1857 if (err < 0)
476 return err;
477 }
478 1857 break;
479
480 default:
481 return AVERROR(ENOSYS);
482 }
483
484 9960 return 0;
485 }
486
487 8137 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 60 times.
✓ Branch 1 taken 62 times.
✓ Branch 2 taken 287 times.
✓ Branch 3 taken 6106 times.
✓ Branch 4 taken 60 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1562 times.
✗ Branch 7 not taken.
8137 switch (unit->type) {
494 60 case HEVC_NAL_VPS:
495 {
496 60 H265RawVPS *vps = unit->content;
497
498 60 err = cbs_h265_write_vps(ctx, pbc, vps);
499
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 60 times.
60 if (err < 0)
500 return err;
501
502 60 err = cbs_h265_replace_vps(ctx, unit);
503
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 60 times.
60 if (err < 0)
504 return err;
505 }
506 60 break;
507
508 62 case HEVC_NAL_SPS:
509 {
510 62 H265RawSPS *sps = unit->content;
511
512 62 err = cbs_h265_write_sps(ctx, pbc, sps);
513
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 62 times.
62 if (err < 0)
514 return err;
515
516 62 err = cbs_h265_replace_sps(ctx, unit);
517
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 62 times.
62 if (err < 0)
518 return err;
519 }
520 62 break;
521
522 287 case HEVC_NAL_PPS:
523 {
524 287 H265RawPPS *pps = unit->content;
525
526 287 err = cbs_h265_write_pps(ctx, pbc, pps);
527
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 287 times.
287 if (err < 0)
528 return err;
529
530 287 err = cbs_h265_replace_pps(ctx, unit);
531
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 287 times.
287 if (err < 0)
532 return err;
533 }
534 287 break;
535
536 6106 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 6106 H265RawSlice *slice = unit->content;
554
555 6106 err = cbs_h265_write_slice_segment_header(ctx, pbc, &slice->header);
556
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6106 times.
6106 if (err < 0)
557 return err;
558
559
1/2
✓ Branch 0 taken 6106 times.
✗ Branch 1 not taken.
6106 if (slice->data) {
560 6106 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 6106 times.
6106 if (err < 0)
564 return err;
565 } else {
566 // No slice data - that was just the header.
567 }
568 }
569 6106 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 1562 case HEVC_NAL_SEI_PREFIX:
588 case HEVC_NAL_SEI_SUFFIX:
589 {
590 1562 err = cbs_h265_write_sei(ctx, pbc, unit->content,
591 1562 unit->type == HEVC_NAL_SEI_PREFIX);
592
593
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1562 times.
1562 if (err < 0)
594 return err;
595 }
596 1562 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 8137 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 51 static av_cold void cbs_h265_close(CodedBitstreamContext *ctx)
697 {
698 51 CodedBitstreamH265Context *h265 = ctx->priv_data;
699 int i;
700
701 51 ff_h2645_packet_uninit(&h265->common.read_packet);
702
703
2/2
✓ Branch 0 taken 816 times.
✓ Branch 1 taken 51 times.
867 for (i = 0; i < FF_ARRAY_ELEMS(h265->vps); i++)
704 816 av_refstruct_unref(&h265->vps[i]);
705
2/2
✓ Branch 0 taken 816 times.
✓ Branch 1 taken 51 times.
867 for (i = 0; i < FF_ARRAY_ELEMS(h265->sps); i++)
706 816 av_refstruct_unref(&h265->sps[i]);
707
2/2
✓ Branch 0 taken 3264 times.
✓ Branch 1 taken 51 times.
3315 for (i = 0; i < FF_ARRAY_ELEMS(h265->pps); i++)
708 3264 av_refstruct_unref(&h265->pps[i]);
709 51 }
710
711 1857 static void cbs_h265_free_sei(AVRefStructOpaque unused, void *content)
712 {
713 1857 H265RawSEI *sei = content;
714 1857 ff_cbs_sei_free_message_list(&sei->message_list);
715 1857 }
716
717 static CodedBitstreamUnitTypeDescriptor cbs_h265_unit_types[] = {
718 CBS_UNIT_TYPE_INTERNAL_REF(HEVC_NAL_VPS, H265RawVPS, extension_data.data),
719 CBS_UNIT_TYPE_INTERNAL_REF(HEVC_NAL_SPS, H265RawSPS, extension_data.data),
720 CBS_UNIT_TYPE_INTERNAL_REF(HEVC_NAL_PPS, H265RawPPS, extension_data.data),
721
722 CBS_UNIT_TYPE_POD(HEVC_NAL_AUD, H265RawAUD),
723 CBS_UNIT_TYPE_POD(HEVC_NAL_FD_NUT, H265RawFiller),
724
725 // Slices of non-IRAP pictures.
726 CBS_UNIT_RANGE_INTERNAL_REF(HEVC_NAL_TRAIL_N, HEVC_NAL_RASL_R,
727 H265RawSlice, data),
728 // Slices of IRAP pictures.
729 CBS_UNIT_RANGE_INTERNAL_REF(HEVC_NAL_BLA_W_LP, HEVC_NAL_CRA_NUT,
730 H265RawSlice, data),
731
732 CBS_UNIT_TYPES_COMPLEX((HEVC_NAL_SEI_PREFIX, HEVC_NAL_SEI_SUFFIX),
733 H265RawSEI, cbs_h265_free_sei),
734
735 CBS_UNIT_TYPE_END_OF_LIST
736 };
737
738 // Macro for the read/write pair.
739 #define SEI_MESSAGE_RW(codec, name) \
740 .read = cbs_ ## codec ## _read_ ## name ## _internal, \
741 .write = cbs_ ## codec ## _write_ ## name ## _internal
742
743 const SEIMessageTypeDescriptor ff_cbs_sei_h265_types[] = {
744 {
745 SEI_TYPE_BUFFERING_PERIOD,
746 1, 0,
747 sizeof(H265RawSEIBufferingPeriod),
748 SEI_MESSAGE_RW(h265, sei_buffering_period),
749 },
750 {
751 SEI_TYPE_PIC_TIMING,
752 1, 0,
753 sizeof(H265RawSEIPicTiming),
754 SEI_MESSAGE_RW(h265, sei_pic_timing),
755 },
756 {
757 SEI_TYPE_PAN_SCAN_RECT,
758 1, 0,
759 sizeof(H265RawSEIPanScanRect),
760 SEI_MESSAGE_RW(h265, sei_pan_scan_rect),
761 },
762 {
763 SEI_TYPE_RECOVERY_POINT,
764 1, 0,
765 sizeof(H265RawSEIRecoveryPoint),
766 SEI_MESSAGE_RW(h265, sei_recovery_point),
767 },
768 {
769 SEI_TYPE_FILM_GRAIN_CHARACTERISTICS,
770 1, 0,
771 sizeof(H265RawFilmGrainCharacteristics),
772 SEI_MESSAGE_RW(h265, film_grain_characteristics),
773 },
774 {
775 SEI_TYPE_DISPLAY_ORIENTATION,
776 1, 0,
777 sizeof(H265RawSEIDisplayOrientation),
778 SEI_MESSAGE_RW(h265, sei_display_orientation),
779 },
780 {
781 SEI_TYPE_ACTIVE_PARAMETER_SETS,
782 1, 0,
783 sizeof(H265RawSEIActiveParameterSets),
784 SEI_MESSAGE_RW(h265, sei_active_parameter_sets),
785 },
786 {
787 SEI_TYPE_DECODED_PICTURE_HASH,
788 0, 1,
789 sizeof(H265RawSEIDecodedPictureHash),
790 SEI_MESSAGE_RW(h265, sei_decoded_picture_hash),
791 },
792 {
793 SEI_TYPE_TIME_CODE,
794 1, 0,
795 sizeof(H265RawSEITimeCode),
796 SEI_MESSAGE_RW(h265, sei_time_code),
797 },
798 {
799 SEI_TYPE_ALPHA_CHANNEL_INFO,
800 1, 0,
801 sizeof(H265RawSEIAlphaChannelInfo),
802 SEI_MESSAGE_RW(h265, sei_alpha_channel_info),
803 },
804 {
805 SEI_TYPE_THREE_DIMENSIONAL_REFERENCE_DISPLAYS_INFO,
806 1, 0,
807 sizeof(H265RawSEI3DReferenceDisplaysInfo),
808 SEI_MESSAGE_RW(h265, sei_3d_reference_displays_info),
809 },
810 SEI_MESSAGE_TYPE_END
811 };
812
813 const CodedBitstreamType ff_cbs_type_h265 = {
814 .codec_id = AV_CODEC_ID_HEVC,
815
816 .priv_data_size = sizeof(CodedBitstreamH265Context),
817
818 .unit_types = cbs_h265_unit_types,
819
820 .split_fragment = &cbs_h265_split_fragment,
821 .read_unit = &cbs_h265_read_nal_unit,
822 .write_unit = &cbs_h265_write_nal_unit,
823 .discarded_unit = &cbs_h265_discarded_nal_unit,
824 .assemble_fragment = &ff_cbs_h2645_assemble_fragment,
825
826 .flush = &cbs_h265_flush,
827 .close = &cbs_h265_close,
828 };
829