FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/bsf/hevc_mp4toannexb.c
Date: 2026-10-17 12:12:06
Exec Total Coverage
Lines: 281 326 86.2%
Functions: 7 7 100.0%
Branches: 161 219 73.5%

Line Branch Exec Source
1 /*
2 * HEVC MP4 to Annex B byte stream format filter
3 * copyright (c) 2015 Anton Khirnov
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #include <string.h>
23
24 #include "libavutil/avassert.h"
25 #include "libavutil/common.h"
26 #include "libavutil/intreadwrite.h"
27 #include "libavutil/mem.h"
28
29 #include "libavcodec/bsf.h"
30 #include "libavcodec/bsf_internal.h"
31 #include "libavcodec/bytestream.h"
32 #include "libavcodec/defs.h"
33
34 #include "libavcodec/hevc/hevc.h"
35
36 #define MIN_HEVCC_LENGTH 23
37 #define MAX_EXTRADATA_NALS 2048
38 #define MAX_PS_CHAIN_DEPTH 16
39 #define MAX_PS_CHECKS_PER_PACKET 128
40
41 /* 32-bit FNV-1a hash algorithm constants */
42 #define FNV1A_32_OFFSET_BASIS 2166136261u
43 #define FNV1A_32_PRIME 16777619u
44
45 93 static inline uint32_t hash_ps(const uint8_t *data, size_t size)
46 {
47 93 uint32_t h = FNV1A_32_OFFSET_BASIS;
48
2/2
✓ Branch 0 taken 1660 times.
✓ Branch 1 taken 93 times.
1753 for (size_t i = 0; i < size; i++) {
49 1660 h ^= data[i];
50 1660 h *= FNV1A_32_PRIME;
51 }
52 93 return h;
53 }
54
55 typedef struct HEVCNALUnit {
56 size_t offset;
57 size_t size;
58 int type;
59 uint32_t hash;
60 int matched;
61 int emit;
62 int next;
63 } HEVCNALUnit;
64
65 typedef struct HEVCBSFContext {
66 uint8_t *extradata;
67 size_t extradata_size;
68 HEVCNALUnit *nals;
69 int nb_nals;
70 int nb_ps;
71 int *ps_buckets;
72 int ps_table_size;
73 uint8_t length_size;
74 int extradata_parsed;
75 int dup_ps_logged;
76 unsigned emitted_types;
77 int sps_seen;
78 } HEVCBSFContext;
79
80 14 static int hevc_extradata_to_annexb(AVBSFContext *ctx,
81 const uint8_t *extradata, size_t extradata_size,
82 uint8_t **out_extradata, int *out_extradata_size)
83 {
84 14 HEVCBSFContext *s = ctx->priv_data;
85 GetByteContext gb, gb_scan;
86 int length_size, num_arrays, i, j;
87 14 int total_nals = 0;
88 14 size_t total_size = 0;
89 14 int ret = 0;
90
91 14 uint8_t *new_extradata = NULL;
92 14 size_t new_extradata_size = 0;
93 14 HEVCNALUnit *new_nals = NULL;
94 14 int nb_nals = 0;
95 14 int *ps_buckets = NULL;
96 14 int ps_table_size = 0;
97 14 int nb_ps = 0;
98
99 /* bytestream2 and AVCodecParameters.extradata_size are both int. */
100
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (extradata_size > INT_MAX) {
101 ✗ av_log(ctx, AV_LOG_ERROR, "Extradata size exceeds INT_MAX\n");
102 ✗ return AVERROR_INVALIDDATA;
103 }
104
105 14 bytestream2_init(&gb, extradata, (int)extradata_size);
106
107 14 bytestream2_skip(&gb, 21);
108 14 length_size = (bytestream2_get_byte(&gb) & 3) + 1;
109 14 num_arrays = bytestream2_get_byte(&gb);
110
111 /* First pass: validate hvcC arrays and compute exact size and NAL count upfront */
112 14 gb_scan = gb;
113
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 13 times.
54 for (i = 0; i < num_arrays; i++) {
114 int type, cnt;
115
116
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 41 times.
41 if (bytestream2_get_bytes_left(&gb_scan) < 3) {
117 ✗ ret = AVERROR_INVALIDDATA;
118 ✗ goto fail;
119 }
120 41 type = bytestream2_get_byte(&gb_scan) & 0x3f;
121 41 cnt = bytestream2_get_be16(&gb_scan);
122
123
7/10
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 13 times.
✓ Branch 2 taken 15 times.
✓ Branch 3 taken 13 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 13 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
41 if (!(type == HEVC_NAL_VPS || type == HEVC_NAL_SPS || type == HEVC_NAL_PPS ||
124 type == HEVC_NAL_SEI_PREFIX || type == HEVC_NAL_SEI_SUFFIX)) {
125 ✗ av_log(ctx, AV_LOG_ERROR, "Invalid NAL unit type in extradata: %d\n",
126 type);
127 ✗ ret = AVERROR_INVALIDDATA;
128 ✗ goto fail;
129 }
130
131
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 40 times.
41 if (cnt > MAX_EXTRADATA_NALS - total_nals) {
132 1 av_log(ctx, AV_LOG_ERROR, "Too many NAL units in extradata: exceeds %d\n",
133 MAX_EXTRADATA_NALS);
134 1 ret = AVERROR_INVALIDDATA;
135 1 goto fail;
136 }
137
138
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 40 times.
81 for (j = 0; j < cnt; j++) {
139 int nalu_len;
140
141
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 41 times.
41 if (bytestream2_get_bytes_left(&gb_scan) < 2) {
142 ✗ ret = AVERROR_INVALIDDATA;
143 ✗ goto fail;
144 }
145 41 nalu_len = bytestream2_get_be16(&gb_scan);
146
147
2/4
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 41 times.
✗ Branch 3 not taken.
82 if (nalu_len < 2 ||
148 41 nalu_len > bytestream2_get_bytes_left(&gb_scan) ||
149
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 41 times.
41 4 + AV_INPUT_BUFFER_PADDING_SIZE + nalu_len > SIZE_MAX - total_size) {
150 ✗ ret = AVERROR_INVALIDDATA;
151 ✗ goto fail;
152 }
153 /* Each hvcC length prefix grows into a 4-byte start code. */
154
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 41 times.
41 if (total_size > (size_t)INT_MAX - 4 - (size_t)nalu_len) {
155 ✗ av_log(ctx, AV_LOG_ERROR, "Annex B extradata size exceeds INT_MAX\n");
156 ✗ ret = AVERROR_INVALIDDATA;
157 ✗ goto fail;
158 }
159 41 total_size += 4 + nalu_len;
160 41 total_nals++;
161 41 bytestream2_skip(&gb_scan, nalu_len);
162 }
163 }
164
165 /* Single allocation for exact extradata buffer and NAL descriptor array */
166
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 if (total_nals > 0) {
167 13 new_extradata = av_malloc(total_size + AV_INPUT_BUFFER_PADDING_SIZE);
168
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if (!new_extradata) {
169 ✗ ret = AVERROR(ENOMEM);
170 ✗ goto fail;
171 }
172 13 new_nals = av_malloc_array(total_nals, sizeof(*new_nals));
173
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if (!new_nals) {
174 ✗ ret = AVERROR(ENOMEM);
175 ✗ goto fail;
176 }
177 }
178
179 /* Second pass: copy NAL units and fill descriptor array without reallocations */
180
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 13 times.
53 for (i = 0; i < num_arrays; i++) {
181 40 int type = bytestream2_get_byte(&gb) & 0x3f;
182 40 int cnt = bytestream2_get_be16(&gb);
183
184
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 40 times.
81 for (j = 0; j < cnt; j++) {
185 41 const int nalu_len = bytestream2_get_be16(&gb);
186
187 41 new_nals[nb_nals].offset = new_extradata_size;
188 41 new_nals[nb_nals].size = 4 + nalu_len;
189 41 new_nals[nb_nals].type = type;
190 41 new_nals[nb_nals].matched = 0;
191 41 new_nals[nb_nals].emit = 1;
192 41 new_nals[nb_nals].hash = 0;
193 41 new_nals[nb_nals].next = -1;
194 41 nb_nals++;
195
196 41 AV_WB32(new_extradata + new_extradata_size, 1); // add the startcode
197 41 bytestream2_get_buffer(&gb, new_extradata + new_extradata_size + 4, nalu_len);
198 41 new_extradata_size += 4 + nalu_len;
199 }
200 }
201
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 if (new_extradata)
202 13 memset(new_extradata + new_extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
203
204
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if (!new_extradata_size)
205 ✗ av_log(ctx, AV_LOG_WARNING, "No parameter sets in the extradata\n");
206
207
3/4
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
13 if (out_extradata && out_extradata_size) {
208
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if (new_extradata_size > INT_MAX) {
209 ✗ av_log(ctx, AV_LOG_ERROR, "Annex B extradata size exceeds INT_MAX\n");
210 ✗ ret = AVERROR_INVALIDDATA;
211 ✗ goto fail;
212 }
213 12 av_freep(out_extradata);
214 12 *out_extradata =
215 12 av_malloc(new_extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
216
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if (!(*out_extradata)) {
217 ✗ ret = AVERROR(ENOMEM);
218 ✗ goto fail;
219 }
220 12 *out_extradata_size = (int)new_extradata_size;
221 12 memcpy(*out_extradata, new_extradata, new_extradata_size);
222 12 memset(*out_extradata + new_extradata_size, 0,
223 AV_INPUT_BUFFER_PADDING_SIZE);
224 }
225
226
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 13 times.
54 for (i = 0; i < nb_nals; i++) {
227
3/4
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 40 times.
✓ Branch 3 taken 1 times.
41 if (new_nals[i].type >= HEVC_NAL_VPS && new_nals[i].type <= HEVC_NAL_PPS)
228 40 nb_ps++;
229 }
230
231
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 if (nb_ps > 0) {
232 13 ps_table_size = 1 << av_ceil_log2(FFMAX(32, nb_ps * 2));
233 13 ps_buckets = av_malloc_array(ps_table_size, sizeof(*ps_buckets));
234
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if (!ps_buckets) {
235 ✗ ret = AVERROR(ENOMEM);
236 ✗ goto fail;
237 }
238
2/2
✓ Branch 0 taken 416 times.
✓ Branch 1 taken 13 times.
429 for (i = 0; i < ps_table_size; i++)
239 416 ps_buckets[i] = -1;
240
241
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 13 times.
54 for (i = 0; i < nb_nals; i++) {
242 41 HEVCNALUnit *nal = &new_nals[i];
243
3/4
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 40 times.
✓ Branch 3 taken 1 times.
41 if (nal->type >= HEVC_NAL_VPS && nal->type <= HEVC_NAL_PPS) {
244 40 nal->hash = hash_ps(new_extradata + nal->offset + 4, nal->size - 4);
245 40 int bucket = nal->hash & (ps_table_size - 1);
246 40 nal->next = ps_buckets[bucket];
247 40 ps_buckets[bucket] = i;
248 }
249 }
250 }
251
252 13 av_freep(&s->nals);
253 13 av_freep(&s->extradata);
254 13 av_freep(&s->ps_buckets);
255 13 s->extradata = new_extradata;
256 13 s->extradata_size = new_extradata_size;
257 13 s->nals = new_nals;
258 13 s->nb_nals = nb_nals;
259 13 s->nb_ps = nb_ps;
260 13 s->ps_buckets = ps_buckets;
261 13 s->ps_table_size = ps_table_size;
262 13 s->length_size = length_size;
263 13 s->extradata_parsed = 1;
264 13 s->dup_ps_logged = 0;
265 13 return 0;
266 1 fail:
267 1 av_freep(&new_extradata);
268 1 av_freep(&new_nals);
269 1 av_freep(&ps_buckets);
270 1 return ret;
271 }
272
273 13 static int hevc_mp4toannexb_init(AVBSFContext *ctx)
274 {
275 int ret;
276
277
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 if (ctx->par_in->extradata_size < MIN_HEVCC_LENGTH ||
278
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 AV_RB24(ctx->par_in->extradata) == 1 ||
279
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 AV_RB32(ctx->par_in->extradata) == 1) {
280 ✗ av_log(ctx, AV_LOG_VERBOSE,
281 "The input looks like it is Annex B already\n");
282 } else {
283 13 ret = hevc_extradata_to_annexb(ctx,
284 13 ctx->par_in->extradata,
285 13 ctx->par_in->extradata_size,
286 13 &ctx->par_out->extradata,
287 13 &ctx->par_out->extradata_size);
288
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 12 times.
13 if (ret < 0)
289 1 return ret;
290 }
291
292 12 return 0;
293 }
294
295 231 static void emit_extradata_type(HEVCBSFContext *s, uint8_t *dst, size_t *out_offset, int type)
296 {
297 231 unsigned bit = 1U << (type - HEVC_NAL_VPS);
298
2/2
✓ Branch 0 taken 166 times.
✓ Branch 1 taken 65 times.
231 if (s->emitted_types & bit)
299 166 return;
300 65 s->emitted_types |= bit;
301
302
2/2
✓ Branch 0 taken 205 times.
✓ Branch 1 taken 65 times.
270 for (int i = 0; i < s->nb_nals; i++) {
303 205 HEVCNALUnit *nal = &s->nals[i];
304
4/4
✓ Branch 0 taken 45 times.
✓ Branch 1 taken 160 times.
✓ Branch 2 taken 21 times.
✓ Branch 3 taken 24 times.
205 if (nal->emit && nal->type == type) {
305 21 memcpy(dst + *out_offset, s->extradata + nal->offset, nal->size);
306 21 *out_offset += nal->size;
307 21 nal->emit = 0;
308
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 14 times.
21 if (type == HEVC_NAL_SPS)
309 7 s->sps_seen = 1;
310 }
311 }
312 }
313
314 456 static void flush_extradata_before(HEVCBSFContext *s, uint8_t *dst, size_t *out_offset,
315 int nalu_type, int has_irap)
316 {
317
2/2
✓ Branch 0 taken 379 times.
✓ Branch 1 taken 77 times.
456 if (!has_irap)
318 379 return;
319
320
6/7
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 39 times.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 13 times.
77 switch (nalu_type) {
321 ✗ case HEVC_NAL_AUD:
322 ✗ break;
323 9 case HEVC_NAL_VPS:
324 9 emit_extradata_type(s, dst, out_offset, HEVC_NAL_VPS);
325 9 break;
326 10 case HEVC_NAL_SPS:
327 10 emit_extradata_type(s, dst, out_offset, HEVC_NAL_VPS);
328 10 emit_extradata_type(s, dst, out_offset, HEVC_NAL_SPS);
329 10 break;
330 39 case HEVC_NAL_PPS:
331 39 emit_extradata_type(s, dst, out_offset, HEVC_NAL_VPS);
332 39 emit_extradata_type(s, dst, out_offset, HEVC_NAL_SPS);
333 39 emit_extradata_type(s, dst, out_offset, HEVC_NAL_PPS);
334 39 break;
335 5 case HEVC_NAL_SEI_PREFIX:
336 5 emit_extradata_type(s, dst, out_offset, HEVC_NAL_VPS);
337 5 emit_extradata_type(s, dst, out_offset, HEVC_NAL_SPS);
338
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if (s->sps_seen)
339 5 emit_extradata_type(s, dst, out_offset, HEVC_NAL_PPS);
340 5 break;
341 1 case HEVC_NAL_SEI_SUFFIX:
342 1 emit_extradata_type(s, dst, out_offset, HEVC_NAL_VPS);
343 1 emit_extradata_type(s, dst, out_offset, HEVC_NAL_SPS);
344 1 emit_extradata_type(s, dst, out_offset, HEVC_NAL_PPS);
345 1 emit_extradata_type(s, dst, out_offset, HEVC_NAL_SEI_PREFIX);
346 1 emit_extradata_type(s, dst, out_offset, HEVC_NAL_SEI_SUFFIX);
347 1 break;
348 13 default:
349
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 if (nalu_type <= HEVC_NAL_RSV_VCL31) {
350 13 emit_extradata_type(s, dst, out_offset, HEVC_NAL_VPS);
351 13 emit_extradata_type(s, dst, out_offset, HEVC_NAL_SPS);
352 13 emit_extradata_type(s, dst, out_offset, HEVC_NAL_PPS);
353 13 emit_extradata_type(s, dst, out_offset, HEVC_NAL_SEI_PREFIX);
354 }
355 13 break;
356 }
357 }
358
359 116 static int hevc_mp4toannexb_filter(AVBSFContext *ctx, AVPacket *out)
360 {
361 116 HEVCBSFContext *s = ctx->priv_data;
362 AVPacket *in;
363 GetByteContext gb;
364
365 116 int got_irap = 0, got_ps = 0, seen_irap_ps = 0;
366 116 int i, ret = 0;
367 116 size_t extradata_size = 0;
368 116 size_t in_annexb_size = 0;
369 116 size_t extra_insert_size = 0;
370 116 size_t total_out_size = 0;
371 116 size_t out_offset = 0;
372 116 uint8_t *extradata = NULL;
373
374 116 ret = ff_bsf_get_packet(ctx, &in);
375
2/2
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 62 times.
116 if (ret < 0)
376 54 return ret;
377
378 extradata =
379 62 av_packet_get_side_data(in, AV_PKT_DATA_NEW_EXTRADATA, &extradata_size);
380
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 61 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
62 if (extradata && extradata_size >= MIN_HEVCC_LENGTH &&
381
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 ((extradata[0] == 1) ||
382 ✗ (extradata[0] == 0 && (extradata[1] || extradata[2] > 1)))) {
383 1 ret = hevc_extradata_to_annexb(ctx, extradata, extradata_size,
384 NULL, NULL);
385
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (ret < 0)
386 ✗ goto fail;
387 1 av_packet_side_data_remove(in->side_data, &in->side_data_elems,
388 AV_PKT_DATA_NEW_EXTRADATA);
389 }
390
391
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 62 times.
62 if (!s->extradata_parsed) {
392 ✗ av_packet_move_ref(out, in);
393 ✗ av_packet_free(&in);
394 ✗ return 0;
395 }
396
397 62 bytestream2_init(&gb, in->data, in->size);
398
399
2/2
✓ Branch 0 taken 188 times.
✓ Branch 1 taken 62 times.
250 for (i = 0; i < s->nb_nals; i++)
400 188 s->nals[i].matched = 0;
401
402 {
403 62 int unmatched_ps = s->nb_ps;
404 62 int ps_checks = 0;
405 62 int max_inband_ps_level = 0;
406
407
2/2
✓ Branch 1 taken 456 times.
✓ Branch 2 taken 62 times.
518 while (bytestream2_get_bytes_left(&gb)) {
408 456 uint32_t nalu_size = 0;
409 int nalu_type;
410
411
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 456 times.
456 if (bytestream2_get_bytes_left(&gb) < s->length_size) {
412 ✗ ret = AVERROR_INVALIDDATA;
413 ✗ goto fail;
414 }
415
2/2
✓ Branch 0 taken 1824 times.
✓ Branch 1 taken 456 times.
2280 for (i = 0; i < s->length_size; i++)
416 1824 nalu_size = (nalu_size << 8) | bytestream2_get_byte(&gb);
417
418
2/4
✓ Branch 0 taken 456 times.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 456 times.
456 if (nalu_size < 2 || nalu_size > bytestream2_get_bytes_left(&gb)) {
419 ✗ ret = AVERROR_INVALIDDATA;
420 ✗ goto fail;
421 }
422
423 456 nalu_type = (bytestream2_peek_byte(&gb) >> 1) & 0x3f;
424 /* Prefix SEI can flush dependent extradata before later VPS/SPS. */
425
4/4
✓ Branch 0 taken 455 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 450 times.
456 if (!got_irap && nalu_type == HEVC_NAL_SEI_PREFIX)
426 5 max_inband_ps_level = HEVC_NAL_PPS - HEVC_NAL_VPS;
427
6/6
✓ Branch 0 taken 455 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 110 times.
✓ Branch 3 taken 345 times.
✓ Branch 4 taken 58 times.
✓ Branch 5 taken 52 times.
456 if (!got_irap && nalu_type >= HEVC_NAL_VPS && nalu_type <= HEVC_NAL_PPS) {
428 58 int inband_level = nalu_type - HEVC_NAL_VPS;
429
2/2
✓ Branch 0 taken 53 times.
✓ Branch 1 taken 5 times.
58 if (inband_level < max_inband_ps_level) {
430 /* Inverted topological order (e.g. PPS before SPS).
431 * Earlier dependencies cannot be suppressed by this out-of-order PS. */
432 } else {
433 53 max_inband_ps_level = inband_level;
434
3/6
✓ Branch 0 taken 53 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 53 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 53 times.
✗ Branch 5 not taken.
53 if (unmatched_ps > 0 && s->ps_buckets &&
435 ps_checks < MAX_PS_CHECKS_PER_PACKET) {
436 uint32_t hash;
437 53 int idx, depth = 0;
438
439 53 ps_checks++;
440 53 hash = hash_ps(gb.buffer, nalu_size);
441 53 idx = s->ps_buckets[hash & (s->ps_table_size - 1)];
442
443
3/4
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 53 times.
✓ Branch 2 taken 22 times.
✗ Branch 3 not taken.
75 while (idx >= 0 && depth++ < MAX_PS_CHAIN_DEPTH) {
444 22 HEVCNALUnit *nal = &s->nals[idx];
445
3/4
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
22 if (nal->type == nalu_type && (nal->size - 4) == nalu_size &&
446
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 nal->hash == hash &&
447
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 !memcmp(s->extradata + nal->offset + 4, gb.buffer, nalu_size)) {
448
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 if (!nal->matched) {
449 20 nal->matched = 1;
450 20 unmatched_ps--;
451 }
452 }
453 22 idx = nal->next;
454 }
455 }
456 }
457 }
458
1/2
✓ Branch 0 taken 456 times.
✗ Branch 1 not taken.
456 if (FFMIN(INT_MAX, SIZE_MAX) < 4ULL + nalu_size ||
459
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 456 times.
456 in_annexb_size > INT_MAX - 4 - nalu_size) {
460 ✗ ret = AVERROR_INVALIDDATA;
461 ✗ goto fail;
462 }
463 456 in_annexb_size += 4 + nalu_size;
464
465 456 bytestream2_skip(&gb, nalu_size);
466
6/6
✓ Branch 0 taken 455 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 110 times.
✓ Branch 3 taken 345 times.
✓ Branch 4 taken 58 times.
✓ Branch 5 taken 52 times.
456 got_ps |= !got_irap && (nalu_type >= HEVC_NAL_VPS && nalu_type <= HEVC_NAL_PPS);
467
4/4
✓ Branch 0 taken 124 times.
✓ Branch 1 taken 332 times.
✓ Branch 2 taken 13 times.
✓ Branch 3 taken 111 times.
456 got_irap |= nalu_type >= HEVC_NAL_BLA_W_LP &&
468 nalu_type <= HEVC_NAL_RSV_IRAP_VCL23;
469 }
470 }
471
4/4
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 49 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 3 times.
62 seen_irap_ps = got_irap && got_ps;
472
473 62 s->emitted_types = 0;
474 62 s->sps_seen = 0;
475
476
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 49 times.
62 if (got_irap) {
477 13 int omitted = 0;
478
479
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 13 times.
54 for (i = 0; i < s->nb_nals; i++) {
480 41 HEVCNALUnit *nal = &s->nals[i];
481
482 41 nal->emit = 1;
483
4/4
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 20 times.
✓ Branch 3 taken 12 times.
41 if (seen_irap_ps && nal->matched &&
484
2/4
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
20 nal->type >= HEVC_NAL_VPS && nal->type <= HEVC_NAL_PPS) {
485 20 nal->emit = 0;
486 20 omitted++;
487 }
488
489
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 20 times.
41 if (nal->emit)
490 21 extra_insert_size += nal->size;
491 }
492
3/4
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
13 if (omitted && !s->dup_ps_logged) {
493 8 av_log(ctx, AV_LOG_VERBOSE,
494 "Omitting %d extradata parameter sets already present in-band\n",
495 omitted);
496 8 s->dup_ps_logged = 1;
497 }
498 } else {
499
2/2
✓ Branch 0 taken 147 times.
✓ Branch 1 taken 49 times.
196 for (i = 0; i < s->nb_nals; i++)
500 147 s->nals[i].emit = 0;
501 }
502
503
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 62 times.
62 if (extra_insert_size > INT_MAX - in_annexb_size) {
504 ✗ ret = AVERROR_INVALIDDATA;
505 ✗ goto fail;
506 }
507 62 total_out_size = in_annexb_size + extra_insert_size;
508
509 62 ret = av_new_packet(out, total_out_size);
510
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 62 times.
62 if (ret < 0)
511 ✗ goto fail;
512
513 62 bytestream2_init(&gb, in->data, in->size);
514
515
2/2
✓ Branch 1 taken 456 times.
✓ Branch 2 taken 62 times.
518 while (bytestream2_get_bytes_left(&gb)) {
516 456 uint32_t nalu_size = 0;
517 int nalu_type;
518
519
2/2
✓ Branch 0 taken 1824 times.
✓ Branch 1 taken 456 times.
2280 for (i = 0; i < s->length_size; i++)
520 1824 nalu_size = (nalu_size << 8) | bytestream2_get_byte(&gb);
521
522 456 nalu_type = (bytestream2_peek_byte(&gb) >> 1) & 0x3f;
523
524 456 flush_extradata_before(s, out->data, &out_offset, nalu_type, got_irap);
525
526
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 446 times.
456 if (nalu_type == HEVC_NAL_SPS)
527 10 s->sps_seen = 1;
528
529 456 AV_WB32(out->data + out_offset, 1);
530 456 out_offset += 4;
531 456 bytestream2_get_buffer(&gb, out->data + out_offset, nalu_size);
532 456 out_offset += nalu_size;
533 }
534
535
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 49 times.
62 if (got_irap)
536 13 emit_extradata_type(s, out->data, &out_offset, HEVC_NAL_SEI_SUFFIX);
537
538 av_assert1(out_offset == out->size);
539
540 62 ret = av_packet_copy_props(out, in);
541
1/2
✓ Branch 0 taken 62 times.
✗ Branch 1 not taken.
62 if (ret < 0)
542 ✗ goto fail;
543
544 62 fail:
545
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 62 times.
62 if (ret < 0)
546 ✗ av_packet_unref(out);
547 62 av_packet_free(&in);
548
549 62 return ret;
550 }
551
552 13 static void hevc_mp4toannexb_close(AVBSFContext *ctx)
553 {
554 13 HEVCBSFContext *s = ctx->priv_data;
555 13 av_freep(&s->nals);
556 13 av_freep(&s->extradata);
557 13 av_freep(&s->ps_buckets);
558 13 }
559
560 static const enum AVCodecID codec_ids[] = {
561 AV_CODEC_ID_HEVC, AV_CODEC_ID_NONE,
562 };
563
564 const FFBitStreamFilter ff_hevc_mp4toannexb_bsf = {
565 .p.name = "hevc_mp4toannexb",
566 .p.codec_ids = codec_ids,
567 .priv_data_size = sizeof(HEVCBSFContext),
568 .init = hevc_mp4toannexb_init,
569 .filter = hevc_mp4toannexb_filter,
570 .close = hevc_mp4toannexb_close,
571 };
572