Coverage Report

Created: 2026-09-02 06:43

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/libde265/libde265/nal-parser.cc
Line
Count
Source
1
/*
2
 * H.265 video codec.
3
 * Copyright (c) 2013-2014 struktur AG, Dirk Farin <farin@struktur.de>
4
 *
5
 * This file is part of libde265.
6
 *
7
 * libde265 is free software: you can redistribute it and/or modify
8
 * it under the terms of the GNU Lesser General Public License as
9
 * published by the Free Software Foundation, either version 3 of
10
 * the License, or (at your option) any later version.
11
 *
12
 * libde265 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
15
 * GNU Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public License
18
 * along with libde265.  If not, see <http://www.gnu.org/licenses/>.
19
 */
20
21
#include "nal-parser.h"
22
23
#include <string.h>
24
#include <assert.h>
25
#include <stdlib.h>
26
#include <stdio.h>
27
#include <stdint.h>
28
#include <limits.h>
29
30
#ifdef HAVE_CONFIG_H
31
#include "config.h"
32
#endif
33
34
35
NAL_unit::NAL_unit()
36
51.8k
  : skipped_bytes(DE265_SKIPPED_BYTES_INITIAL_SIZE)
37
51.8k
{
38
51.8k
}
39
40
NAL_unit::~NAL_unit()
41
51.8k
{
42
51.8k
  free(nal_data);
43
51.8k
}
44
45
void NAL_unit::clear()
46
51.8k
{
47
51.8k
  header = nal_header();
48
51.8k
  pts = 0;
49
51.8k
  user_data = nullptr;
50
51
  // set size to zero but keep memory
52
51.8k
  data_size = 0;
53
54
51.8k
  skipped_bytes.clear();
55
51.8k
}
56
57
LIBDE265_CHECK_RESULT bool NAL_unit::resize(int new_size)
58
103k
{
59
103k
  if (capacity < new_size) {
60
    // Grow the buffer geometrically (1.5x) rather than to the exact requested
61
    // size. NAL_Parser::push_data() appends to the pending NAL one input chunk
62
    // at a time, increasing the request by a roughly constant amount each call.
63
    // With exact-size allocation every chunk would reallocate and copy the
64
    // whole accumulated buffer (O(n^2) for a single oversized NAL); spare
65
    // capacity amortizes the total copying to O(n). Here new_size > capacity >= 0,
66
    // so the 1.5x term is computed in 64 bits and only used when it both exceeds
67
    // the request and still fits in 'int'.
68
51.8k
    int alloc_size = new_size;
69
51.8k
    int64_t grow = static_cast<int64_t>(capacity) + capacity / 2;
70
51.8k
    if (grow > new_size && grow <= INT_MAX) {
71
0
      alloc_size = static_cast<int>(grow);
72
0
    }
73
74
51.8k
    unsigned char* newbuffer = static_cast<unsigned char*>(malloc(alloc_size));
75
51.8k
    if (newbuffer == nullptr) {
76
0
      return false;
77
0
    }
78
79
51.8k
    if (nal_data != nullptr) {
80
0
      memcpy(newbuffer, nal_data, data_size);
81
0
      free(nal_data);
82
0
    }
83
84
51.8k
    nal_data = newbuffer;
85
51.8k
    capacity = alloc_size;
86
51.8k
  }
87
103k
  return true;
88
103k
}
89
90
LIBDE265_CHECK_RESULT bool NAL_unit::append(const unsigned char* in_data, int n)
91
0
{
92
0
  if (!resize(data_size + n)) {
93
0
    return false;
94
0
  }
95
0
  if (n > 0) {
96
0
    memcpy(nal_data + data_size, in_data, n);
97
0
  }
98
0
  data_size += n;
99
0
  return true;
100
0
}
101
102
bool LIBDE265_CHECK_RESULT NAL_unit::set_data(const unsigned char* in_data, int n)
103
51.8k
{
104
51.8k
  if (!resize(n)) {
105
0
    return false;
106
0
  }
107
51.8k
  if (n > 0) {
108
51.8k
    memcpy(nal_data, in_data, n);
109
51.8k
  }
110
51.8k
  data_size = n;
111
51.8k
  return true;
112
51.8k
}
113
114
void NAL_unit::insert_skipped_byte(uint32_t pos)
115
102k
{
116
102k
  skipped_bytes.push_back(pos);
117
102k
}
118
119
uint32_t NAL_unit::num_skipped_bytes_before(uint32_t byte_position, uint32_t headerLength) const
120
18.2k
{
121
18.2k
  if (skipped_bytes.empty()) {
122
1.06k
    return 0;
123
1.06k
  }
124
125
79.7k
  for (int k=skipped_bytes.size()-1;k>=0;k--)
126
76.8k
    if (skipped_bytes[k] >= headerLength &&
127
76.7k
        skipped_bytes[k]-headerLength <= byte_position) {
128
14.2k
      return k+1;
129
14.2k
    }
130
131
2.88k
  return 0;
132
17.1k
}
133
134
void NAL_unit::remove_stuffing_bytes()
135
51.8k
{
136
  // Remove emulation-prevention bytes: every 0x03 that immediately follows two
137
  // 0x00 bytes is dropped (and the zero-run reset, so 00 00 03 03 keeps the
138
  // trailing 03). This is done in a single in-place forward-compaction pass in
139
  // O(n) time. A previous implementation called memmove() on the remaining tail
140
  // for each removed byte, which is O(n^2) and can be abused by a payload that
141
  // is densely packed with 00 00 03 triplets.
142
143
51.8k
  uint8_t* d = data();
144
51.8k
  const int n = size();
145
146
51.8k
  int w = 0;       // write position == length of the compacted output so far
147
51.8k
  int zeros = 0;   // number of consecutive 0x00 bytes already written to output
148
149
6.12M
  for (int r=0; r<n; r++) {
150
6.07M
    uint8_t b = d[r];
151
152
6.07M
    if (zeros >= 2 && b == 3) {
153
      // 'r' is the position of this byte in the original (uncompacted) NAL,
154
      // which equals (compacted position) + num_skipped_bytes() — the value the
155
      // previous memmove-based code recorded here.
156
102k
      insert_skipped_byte(r);
157
102k
      zeros = 0;
158
102k
      continue;
159
102k
    }
160
161
5.96M
    d[w++] = b;
162
5.96M
    zeros = (b == 0) ? zeros + 1 : 0;
163
5.96M
  }
164
165
51.8k
  set_size(w);
166
51.8k
}
167
168
169
170
171
172
33.9k
NAL_Parser::NAL_Parser() = default;
173
174
175
NAL_Parser::~NAL_Parser()
176
33.9k
{
177
  // --- free NAL queues ---
178
179
  // empty NAL queue
180
181
33.9k
  NAL_unit* nal;
182
44.0k
  while ( (nal = pop_from_NAL_queue()) ) {
183
10.0k
    free_NAL_unit(nal);
184
10.0k
  }
185
186
  // free the pending input NAL
187
188
33.9k
  if (pending_input_NAL != nullptr) {
189
0
    free_NAL_unit(pending_input_NAL);
190
0
  }
191
192
  // free all NALs in free-list
193
194
85.7k
  for (size_t i=0;i<NAL_free_list.size();i++) {
195
51.8k
    delete NAL_free_list[i];
196
51.8k
  }
197
33.9k
}
198
199
200
LIBDE265_CHECK_RESULT NAL_unit* NAL_Parser::alloc_NAL_unit(int size)
201
51.8k
{
202
51.8k
  NAL_unit* nal;
203
204
  // --- get NAL-unit object ---
205
206
51.8k
  if (NAL_free_list.size() > 0) {
207
0
    nal = NAL_free_list.back();
208
0
    NAL_free_list.pop_back();
209
0
  }
210
51.8k
  else {
211
51.8k
    nal = new NAL_unit;
212
51.8k
  }
213
214
51.8k
  nal->clear();
215
51.8k
  if (!nal->resize(size)) {
216
0
    free_NAL_unit(nal);
217
0
    return nullptr;
218
0
  }
219
220
51.8k
  return nal;
221
51.8k
}
222
223
void NAL_Parser::free_NAL_unit(NAL_unit* nal)
224
51.8k
{
225
51.8k
  if (nal == nullptr) {
226
    // Allow calling with nullptr just like regular "free()"
227
0
    return;
228
0
  }
229
51.8k
  if (NAL_free_list.size() < DE265_NAL_FREE_LIST_SIZE) {
230
51.8k
    NAL_free_list.push_back(nal);
231
51.8k
  }
232
34
  else {
233
34
    delete nal;
234
34
  }
235
51.8k
}
236
237
NAL_unit* NAL_Parser::pop_from_NAL_queue()
238
85.7k
{
239
85.7k
  if (NAL_queue.empty()) {
240
33.9k
    return nullptr;
241
33.9k
  }
242
51.7k
  else {
243
51.7k
    NAL_unit* nal = NAL_queue.front();
244
51.7k
    NAL_queue.pop();
245
246
51.7k
    nBytes_in_NAL_queue -= nal->size();
247
248
51.7k
    return nal;
249
51.7k
  }
250
85.7k
}
251
252
void NAL_Parser::push_to_NAL_queue(NAL_unit* nal)
253
51.8k
{
254
51.8k
  NAL_queue.push(nal);
255
51.8k
  nBytes_in_NAL_queue += nal->size();
256
51.8k
}
257
258
de265_error NAL_Parser::push_data(const unsigned char* data, int len,
259
                                  de265_PTS pts, void* user_data)
260
0
{
261
0
  end_of_frame = false;
262
263
0
  if (pending_input_NAL == nullptr) {
264
0
    pending_input_NAL = alloc_NAL_unit(len+3);
265
0
    if (pending_input_NAL == nullptr) {
266
0
      return DE265_ERROR_OUT_OF_MEMORY;
267
0
    }
268
0
    pending_input_NAL->pts = pts;
269
0
    pending_input_NAL->user_data = user_data;
270
0
  }
271
272
0
  NAL_unit* nal = pending_input_NAL; // shortcut
273
274
  // Resize output buffer so that complete input would fit.
275
  // We add 3, because in the worst case 3 extra bytes are created for an input byte.
276
0
  if (!nal->resize(nal->size() + len + 3)) {
277
0
    return DE265_ERROR_OUT_OF_MEMORY;
278
0
  }
279
280
0
  unsigned char* out = nal->data() + nal->size();
281
282
0
  for (int i=0;i<len;i++) {
283
    /*
284
    printf("state=%d input=%02x (%p) (output size: %d)\n",ctx->input_push_state, *data, data,
285
           out - ctx->nal_data.data);
286
    */
287
288
0
    switch (input_push_state) {
289
0
    case 0:
290
0
    case 1:
291
0
      if (*data == 0) { input_push_state++; }
292
0
      else { input_push_state=0; }
293
0
      break;
294
0
    case 2:
295
0
      if      (*data == 1) { input_push_state=3; } // nal->clear_skipped_bytes(); }
296
0
      else if (*data == 0) { } // *out++ = 0; }
297
0
      else { input_push_state=0; }
298
0
      break;
299
0
    case 3:
300
0
      *out++ = *data;
301
0
      input_push_state = 4;
302
0
      break;
303
0
    case 4:
304
0
      *out++ = *data;
305
0
      input_push_state = 5;
306
0
      break;
307
308
0
    case 5:
309
0
      if (*data==0) { input_push_state=6; }
310
0
      else { *out++ = *data; }
311
0
      break;
312
313
0
    case 6:
314
0
      if (*data==0) { input_push_state=7; }
315
0
      else {
316
0
        *out++ = 0;
317
0
        *out++ = *data;
318
0
        input_push_state=5;
319
0
      }
320
0
      break;
321
322
0
    case 7:
323
0
      if      (*data==0) { *out++ = 0; }
324
0
      else if (*data==3) {
325
0
        *out++ = 0; *out++ = 0; input_push_state=5;
326
327
        // remember which byte we removed
328
0
        nal->insert_skipped_byte((out - nal->data()) + nal->num_skipped_bytes());
329
0
      }
330
0
      else if (*data==1) {
331
332
#if DEBUG_INSERT_STREAM_ERRORS
333
        if ((rand()%100)<90 && nal_data.size>0) {
334
          int pos = rand()%nal_data.size;
335
          int bit = rand()%8;
336
          nal->nal_data.data[pos] ^= 1<<bit;
337
338
          //printf("inserted error...\n");
339
        }
340
#endif
341
342
        // enforce the maximum NAL size: drop an oversized NAL and resync
343
0
        if (!nal_size_within_limit(out - nal->data())) {
344
0
          free_NAL_unit(pending_input_NAL);
345
0
          pending_input_NAL = nullptr;
346
0
          input_push_state = 0;
347
0
          return DE265_ERROR_NAL_SIZE_EXCEEDS_SECURITY_LIMIT;
348
0
        }
349
350
0
        nal->set_size(out - nal->data());;
351
352
        // push this NAL decoder queue
353
0
        push_to_NAL_queue(nal);
354
355
356
        // initialize new, empty NAL unit
357
358
0
        pending_input_NAL = alloc_NAL_unit(len+3);
359
0
        if (pending_input_NAL == nullptr) {
360
0
          return DE265_ERROR_OUT_OF_MEMORY;
361
0
        }
362
0
        pending_input_NAL->pts = pts;
363
0
        pending_input_NAL->user_data = user_data;
364
0
        nal = pending_input_NAL;
365
0
        out = nal->data();
366
367
0
        input_push_state=3;
368
        //nal->clear_skipped_bytes();
369
0
      }
370
0
      else {
371
0
        *out++ = 0;
372
0
        *out++ = 0;
373
0
        *out++ = *data;
374
375
0
        input_push_state=5;
376
0
      }
377
0
      break;
378
0
    }
379
380
0
    data++;
381
0
  }
382
383
0
  nal->set_size(out - nal->data());
384
385
  // Enforce the maximum NAL size on the still-incomplete pending NAL. This bounds
386
  // memory when a single NAL grows across many push_data() calls without ever
387
  // reaching a start code. The oversized pending NAL is dropped and the parser
388
  // resyncs at the next start code.
389
0
  if (!nal_size_within_limit(nal->size())) {
390
0
    free_NAL_unit(pending_input_NAL);
391
0
    pending_input_NAL = nullptr;
392
0
    input_push_state = 0;
393
0
    return DE265_ERROR_NAL_SIZE_EXCEEDS_SECURITY_LIMIT;
394
0
  }
395
396
0
  return DE265_OK;
397
0
}
398
399
400
de265_error NAL_Parser::push_NAL(const unsigned char* data, int len,
401
                                 de265_PTS pts, void* user_data)
402
108k
{
403
404
  // Cannot use byte-stream input and NAL input at the same time.
405
108k
  assert(pending_input_NAL == nullptr);
406
407
  // A NAL unit must at least contain its two-byte header. Reject anything shorter
408
  // (including a negative length) before touching any state: a zero-length unit
409
  // would otherwise end up as a memcpy() with a NULL destination and, once queued,
410
  // would fail header parsing in decode_NAL() and abort decoding of the stream.
411
108k
  if (len < 2) {
412
56.8k
    return DE265_ERROR_INVALID_ARGUMENT;
413
56.8k
  }
414
415
51.8k
  end_of_frame = false;
416
417
  // enforce the maximum NAL size to bound memory usage
418
51.8k
  if (!nal_size_within_limit(len)) {
419
0
    return DE265_ERROR_NAL_SIZE_EXCEEDS_SECURITY_LIMIT;
420
0
  }
421
422
51.8k
  NAL_unit* nal = alloc_NAL_unit(len);
423
51.8k
  if (nal == nullptr || !nal->set_data(data, len)) {
424
0
    free_NAL_unit(nal);
425
0
    return DE265_ERROR_OUT_OF_MEMORY;
426
0
  }
427
51.8k
  nal->pts = pts;
428
51.8k
  nal->user_data = user_data;
429
430
51.8k
  nal->remove_stuffing_bytes();
431
432
51.8k
  push_to_NAL_queue(nal);
433
434
51.8k
  return DE265_OK;
435
51.8k
}
436
437
438
de265_error NAL_Parser::flush_data()
439
21.4k
{
440
21.4k
  if (pending_input_NAL) {
441
0
    NAL_unit* nal = pending_input_NAL;
442
0
    uint8_t null[2] = { 0,0 };
443
444
    // append bytes that are implied by the push state
445
446
0
    if (input_push_state==6) {
447
0
      if (!nal->append(null,1)) {
448
0
        return DE265_ERROR_OUT_OF_MEMORY;
449
0
      }
450
0
    }
451
0
    if (input_push_state==7) {
452
0
      if (!nal->append(null,2)) {
453
0
        return DE265_ERROR_OUT_OF_MEMORY;
454
0
      }
455
0
    }
456
457
458
    // only push the NAL if it contains at least the NAL header
459
460
0
    if (input_push_state>=5) {
461
0
      push_to_NAL_queue(nal);
462
0
      pending_input_NAL = nullptr;
463
0
    }
464
465
0
    input_push_state = 0;
466
0
  }
467
468
21.4k
  return DE265_OK;
469
21.4k
}
470
471
472
void NAL_Parser::remove_pending_input_data()
473
0
{
474
  // --- remove pending input data ---
475
476
0
  if (pending_input_NAL) {
477
0
    free_NAL_unit(pending_input_NAL);
478
0
    pending_input_NAL = nullptr;
479
0
  }
480
481
0
  for (;;) {
482
0
    NAL_unit* nal = pop_from_NAL_queue();
483
0
    if (nal) { free_NAL_unit(nal); }
484
0
    else break;
485
0
  }
486
487
0
  input_push_state = 0;
488
0
  nBytes_in_NAL_queue = 0;
489
0
}