Coverage Report

Created: 2026-02-14 07:11

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/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
28
#ifdef HAVE_CONFIG_H
29
#include "config.h"
30
#endif
31
32
33
NAL_unit::NAL_unit()
34
27.5k
  : skipped_bytes(DE265_SKIPPED_BYTES_INITIAL_SIZE)
35
27.5k
{
36
27.5k
  pts=0;
37
27.5k
  user_data = NULL;
38
39
27.5k
  nal_data = NULL;
40
27.5k
  data_size = 0;
41
27.5k
  capacity = 0;
42
27.5k
}
43
44
NAL_unit::~NAL_unit()
45
27.5k
{
46
27.5k
  free(nal_data);
47
27.5k
}
48
49
void NAL_unit::clear()
50
27.5k
{
51
27.5k
  header = nal_header();
52
27.5k
  pts = 0;
53
27.5k
  user_data = NULL;
54
55
  // set size to zero but keep memory
56
27.5k
  data_size = 0;
57
58
27.5k
  skipped_bytes.clear();
59
27.5k
}
60
61
LIBDE265_CHECK_RESULT bool NAL_unit::resize(int new_size)
62
55.1k
{
63
55.1k
  if (capacity < new_size) {
64
18.3k
    unsigned char* newbuffer = (unsigned char*)malloc(new_size);
65
18.3k
    if (newbuffer == NULL) {
66
0
      return false;
67
0
    }
68
69
18.3k
    if (nal_data != NULL) {
70
0
      memcpy(newbuffer, nal_data, data_size);
71
0
      free(nal_data);
72
0
    }
73
74
18.3k
    nal_data = newbuffer;
75
18.3k
    capacity = new_size;
76
18.3k
  }
77
55.1k
  return true;
78
55.1k
}
79
80
LIBDE265_CHECK_RESULT bool NAL_unit::append(const unsigned char* in_data, int n)
81
0
{
82
0
  if (!resize(data_size + n)) {
83
0
    return false;
84
0
  }
85
0
  memcpy(nal_data + data_size, in_data, n);
86
0
  data_size += n;
87
0
  return true;
88
0
}
89
90
bool LIBDE265_CHECK_RESULT NAL_unit::set_data(const unsigned char* in_data, int n)
91
27.5k
{
92
27.5k
  if (!resize(n)) {
93
0
    return false;
94
0
  }
95
27.5k
  memcpy(nal_data, in_data, n);
96
27.5k
  data_size = n;
97
27.5k
  return true;
98
27.5k
}
99
100
void NAL_unit::insert_skipped_byte(int pos)
101
98.4k
{
102
98.4k
  skipped_bytes.push_back(pos);
103
98.4k
}
104
105
int NAL_unit::num_skipped_bytes_before(int byte_position, int headerLength) const
106
454
{
107
8.40k
  for (int k=skipped_bytes.size()-1;k>=0;k--)
108
8.02k
    if (skipped_bytes[k] >= headerLength &&
109
7.99k
        skipped_bytes[k]-headerLength <= byte_position) {
110
82
      return k+1;
111
82
    }
112
113
372
  return 0;
114
454
}
115
116
void NAL_unit::remove_stuffing_bytes()
117
27.5k
{
118
27.5k
  uint8_t* p = data();
119
120
6.40M
  for (int i=0;i<size()-2;i++)
121
6.37M
    {
122
#if 0
123
        for (int k=i;k<i+64;k++) 
124
          if (i*0+k<size()) {
125
            printf("%c%02x", (k==i) ? '[':' ', data()[k]);
126
          }
127
        printf("\n");
128
#endif
129
130
6.37M
      if (p[2]!=3 && p[2]!=0) {
131
        // fast forward 3 bytes (2+1)
132
3.87M
        p+=2;
133
3.87M
        i+=2;
134
3.87M
      }
135
2.50M
      else {
136
2.50M
        if (p[0]==0 && p[1]==0 && p[2]==3) {
137
          //printf("SKIP NAL @ %d\n",i+2+num_skipped_bytes);
138
98.4k
          insert_skipped_byte(i+2 + num_skipped_bytes());
139
140
98.4k
          memmove(p+2, p+3, size()-i-3);
141
98.4k
          set_size(size()-1);
142
143
98.4k
          p++;
144
98.4k
          i++;
145
98.4k
        }
146
2.50M
      }
147
148
6.37M
      p++;
149
6.37M
    }
150
27.5k
}
151
152
153
154
155
156
NAL_Parser::NAL_Parser()
157
5.57k
{
158
5.57k
  end_of_stream = false;
159
5.57k
  end_of_frame = false;
160
5.57k
  input_push_state = 0;
161
5.57k
  pending_input_NAL = NULL;
162
5.57k
  nBytes_in_NAL_queue = 0;
163
5.57k
}
164
165
166
NAL_Parser::~NAL_Parser()
167
5.57k
{
168
  // --- free NAL queues ---
169
170
  // empty NAL queue
171
172
5.57k
  NAL_unit* nal;
173
10.0k
  while ( (nal = pop_from_NAL_queue()) ) {
174
4.49k
    free_NAL_unit(nal);
175
4.49k
  }
176
177
  // free the pending input NAL
178
179
5.57k
  if (pending_input_NAL != NULL) {
180
0
    free_NAL_unit(pending_input_NAL);
181
0
  }
182
183
  // free all NALs in free-list
184
185
24.2k
  for (size_t i=0;i<NAL_free_list.size();i++) {
186
18.6k
    delete NAL_free_list[i];
187
18.6k
  }
188
5.57k
}
189
190
191
LIBDE265_CHECK_RESULT NAL_unit* NAL_Parser::alloc_NAL_unit(int size)
192
27.5k
{
193
27.5k
  NAL_unit* nal;
194
195
  // --- get NAL-unit object ---
196
197
27.5k
  if (NAL_free_list.size() > 0) {
198
0
    nal = NAL_free_list.back();
199
0
    NAL_free_list.pop_back();
200
0
  }
201
27.5k
  else {
202
27.5k
    nal = new NAL_unit;
203
27.5k
  }
204
205
27.5k
  nal->clear();
206
27.5k
  if (!nal->resize(size)) {
207
0
    free_NAL_unit(nal);
208
0
    return NULL;
209
0
  }
210
211
27.5k
  return nal;
212
27.5k
}
213
214
void NAL_Parser::free_NAL_unit(NAL_unit* nal)
215
27.5k
{
216
27.5k
  if (nal == NULL) {
217
    // Allow calling with NULL just like regular "free()"
218
0
    return;
219
0
  }
220
27.5k
  if (NAL_free_list.size() < DE265_NAL_FREE_LIST_SIZE) {
221
18.6k
    NAL_free_list.push_back(nal);
222
18.6k
  }
223
8.88k
  else {
224
8.88k
    delete nal;
225
8.88k
  }
226
27.5k
}
227
228
NAL_unit* NAL_Parser::pop_from_NAL_queue()
229
33.1k
{
230
33.1k
  if (NAL_queue.empty()) {
231
5.57k
    return NULL;
232
5.57k
  }
233
27.5k
  else {
234
27.5k
    NAL_unit* nal = NAL_queue.front();
235
27.5k
    NAL_queue.pop();
236
237
27.5k
    nBytes_in_NAL_queue -= nal->size();
238
239
27.5k
    return nal;
240
27.5k
  }
241
33.1k
}
242
243
void NAL_Parser::push_to_NAL_queue(NAL_unit* nal)
244
27.5k
{
245
27.5k
  NAL_queue.push(nal);
246
27.5k
  nBytes_in_NAL_queue += nal->size();
247
27.5k
}
248
249
de265_error NAL_Parser::push_data(const unsigned char* data, int len,
250
                                  de265_PTS pts, void* user_data)
251
0
{
252
0
  end_of_frame = false;
253
254
0
  if (pending_input_NAL == NULL) {
255
0
    pending_input_NAL = alloc_NAL_unit(len+3);
256
0
    if (pending_input_NAL == NULL) {
257
0
      return DE265_ERROR_OUT_OF_MEMORY;
258
0
    }
259
0
    pending_input_NAL->pts = pts;
260
0
    pending_input_NAL->user_data = user_data;
261
0
  }
262
263
0
  NAL_unit* nal = pending_input_NAL; // shortcut
264
265
  // Resize output buffer so that complete input would fit.
266
  // We add 3, because in the worst case 3 extra bytes are created for an input byte.
267
0
  if (!nal->resize(nal->size() + len + 3)) {
268
0
    return DE265_ERROR_OUT_OF_MEMORY;
269
0
  }
270
271
0
  unsigned char* out = nal->data() + nal->size();
272
273
0
  for (int i=0;i<len;i++) {
274
    /*
275
    printf("state=%d input=%02x (%p) (output size: %d)\n",ctx->input_push_state, *data, data,
276
           out - ctx->nal_data.data);
277
    */
278
279
0
    switch (input_push_state) {
280
0
    case 0:
281
0
    case 1:
282
0
      if (*data == 0) { input_push_state++; }
283
0
      else { input_push_state=0; }
284
0
      break;
285
0
    case 2:
286
0
      if      (*data == 1) { input_push_state=3; } // nal->clear_skipped_bytes(); }
287
0
      else if (*data == 0) { } // *out++ = 0; }
288
0
      else { input_push_state=0; }
289
0
      break;
290
0
    case 3:
291
0
      *out++ = *data;
292
0
      input_push_state = 4;
293
0
      break;
294
0
    case 4:
295
0
      *out++ = *data;
296
0
      input_push_state = 5;
297
0
      break;
298
299
0
    case 5:
300
0
      if (*data==0) { input_push_state=6; }
301
0
      else { *out++ = *data; }
302
0
      break;
303
304
0
    case 6:
305
0
      if (*data==0) { input_push_state=7; }
306
0
      else {
307
0
        *out++ = 0;
308
0
        *out++ = *data;
309
0
        input_push_state=5;
310
0
      }
311
0
      break;
312
313
0
    case 7:
314
0
      if      (*data==0) { *out++ = 0; }
315
0
      else if (*data==3) {
316
0
        *out++ = 0; *out++ = 0; input_push_state=5;
317
318
        // remember which byte we removed
319
0
        nal->insert_skipped_byte((out - nal->data()) + nal->num_skipped_bytes());
320
0
      }
321
0
      else if (*data==1) {
322
323
#if DEBUG_INSERT_STREAM_ERRORS
324
        if ((rand()%100)<90 && nal_data.size>0) {
325
          int pos = rand()%nal_data.size;
326
          int bit = rand()%8;
327
          nal->nal_data.data[pos] ^= 1<<bit;
328
329
          //printf("inserted error...\n");
330
        }
331
#endif
332
333
0
        nal->set_size(out - nal->data());;
334
335
        // push this NAL decoder queue
336
0
        push_to_NAL_queue(nal);
337
338
339
        // initialize new, empty NAL unit
340
341
0
        pending_input_NAL = alloc_NAL_unit(len+3);
342
0
        if (pending_input_NAL == NULL) {
343
0
          return DE265_ERROR_OUT_OF_MEMORY;
344
0
        }
345
0
        pending_input_NAL->pts = pts;
346
0
        pending_input_NAL->user_data = user_data;
347
0
        nal = pending_input_NAL;
348
0
        out = nal->data();
349
350
0
        input_push_state=3;
351
        //nal->clear_skipped_bytes();
352
0
      }
353
0
      else {
354
0
        *out++ = 0;
355
0
        *out++ = 0;
356
0
        *out++ = *data;
357
358
0
        input_push_state=5;
359
0
      }
360
0
      break;
361
0
    }
362
363
0
    data++;
364
0
  }
365
366
0
  nal->set_size(out - nal->data());
367
0
  return DE265_OK;
368
0
}
369
370
371
de265_error NAL_Parser::push_NAL(const unsigned char* data, int len,
372
                                 de265_PTS pts, void* user_data)
373
27.5k
{
374
375
  // Cannot use byte-stream input and NAL input at the same time.
376
27.5k
  assert(pending_input_NAL == NULL);
377
378
27.5k
  end_of_frame = false;
379
380
27.5k
  NAL_unit* nal = alloc_NAL_unit(len);
381
27.5k
  if (nal == NULL || !nal->set_data(data, len)) {
382
0
    free_NAL_unit(nal);
383
0
    return DE265_ERROR_OUT_OF_MEMORY;
384
0
  }
385
27.5k
  nal->pts = pts;
386
27.5k
  nal->user_data = user_data;
387
388
27.5k
  nal->remove_stuffing_bytes();
389
390
27.5k
  push_to_NAL_queue(nal);
391
392
27.5k
  return DE265_OK;
393
27.5k
}
394
395
396
de265_error NAL_Parser::flush_data()
397
10.0k
{
398
10.0k
  if (pending_input_NAL) {
399
0
    NAL_unit* nal = pending_input_NAL;
400
0
    uint8_t null[2] = { 0,0 };
401
402
    // append bytes that are implied by the push state
403
404
0
    if (input_push_state==6) {
405
0
      if (!nal->append(null,1)) {
406
0
        return DE265_ERROR_OUT_OF_MEMORY;
407
0
      }
408
0
    }
409
0
    if (input_push_state==7) {
410
0
      if (!nal->append(null,2)) {
411
0
        return DE265_ERROR_OUT_OF_MEMORY;
412
0
      }
413
0
    }
414
415
416
    // only push the NAL if it contains at least the NAL header
417
418
0
    if (input_push_state>=5) {
419
0
      push_to_NAL_queue(nal);
420
0
      pending_input_NAL = NULL;
421
0
    }
422
423
0
    input_push_state = 0;
424
0
  }
425
426
10.0k
  return DE265_OK;
427
10.0k
}
428
429
430
void NAL_Parser::remove_pending_input_data()
431
0
{
432
  // --- remove pending input data ---
433
434
0
  if (pending_input_NAL) {
435
0
    free_NAL_unit(pending_input_NAL);
436
0
    pending_input_NAL = NULL;
437
0
  }
438
439
0
  for (;;) {
440
0
    NAL_unit* nal = pop_from_NAL_queue();
441
0
    if (nal) { free_NAL_unit(nal); }
442
0
    else break;
443
0
  }
444
445
0
  input_push_state = 0;
446
0
  nBytes_in_NAL_queue = 0;
447
0
}