Coverage Report

Created: 2026-10-27 06:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libde265/libde265/decctx.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 "decctx.h"
22
#include "util.h"
23
#include "sao.h"
24
#include "sei.h"
25
#include "deblock.h"
26
27
#include <algorithm>
28
#include <utility>
29
#include <string.h>
30
#include <assert.h>
31
#include <stdlib.h>
32
#include <stdio.h>
33
#include <math.h>
34
35
#include "fallback.h"
36
37
#ifdef HAVE_CONFIG_H
38
#include "config.h"
39
#endif
40
41
#ifdef HAVE_SSE4_1
42
#include "x86/sse.h"
43
#endif
44
45
#ifdef HAVE_ARM32
46
#include "arm32/arm.h"
47
#endif
48
49
#define SAVE_INTERMEDIATE_IMAGES 0
50
51
#if SAVE_INTERMEDIATE_IMAGES
52
#include "visualize.h"
53
#endif
54
55
extern void thread_decode_CTB_row(void* d);
56
extern void thread_decode_slice_segment(void* d);
57
58
59
thread_context::thread_context()
60
13.0k
{
61
  // There is an interesting issue here. When aligning _coeffBuf to 16 bytes offset with
62
  // __attribute__((align(16))), the following statement is optimized away since the
63
  // compiler assumes that the pointer would be 16-byte aligned. However, this is not the
64
  // case when the structure has been dynamically allocated. In this case, the base can
65
  // also be at 8 byte offsets (at least with MingW,32 bit).
66
13.0k
  int offset = ((uintptr_t)_coeffBuf) & 0xf;
67
68
13.0k
  if (offset == 0) {
69
0
    coeffBuf = _coeffBuf;
70
0
  }
71
13.0k
  else {
72
13.0k
    coeffBuf = (int16_t *) (((uint8_t *)_coeffBuf) + (16-offset));
73
13.0k
  }
74
75
13.0k
  memset(coeffBuf, 0, 32*32*sizeof(int16_t));
76
13.0k
}
77
78
79
slice_unit::slice_unit(decoder_context* decctx)
80
8.40k
  : nal(nullptr),
81
8.40k
    shdr(nullptr),
82
8.40k
    imgunit(nullptr),
83
8.40k
    flush_reorder_buffer(false),
84
8.40k
    nThreads(0),
85
8.40k
    first_decoded_CTB_RS(-1),
86
8.40k
    last_decoded_CTB_RS(-1),
87
8.40k
    thread_contexts(nullptr),
88
8.40k
    ctx(decctx)
89
8.40k
{
90
8.40k
  state = Unprocessed;
91
8.40k
  nThreadContexts = 0;
92
8.40k
}
93
94
slice_unit::~slice_unit()
95
8.40k
{
96
  // Return our NAL to the reuse pool. (Letting the unique_ptr delete it would be
97
  // memory-safe too, but would bypass pooling.)
98
8.40k
  ctx->nal_parser.free_NAL_unit(std::move(nal));
99
100
8.40k
  if (thread_contexts) {
101
1.06k
    delete[] thread_contexts;
102
1.06k
  }
103
8.40k
}
104
105
106
void slice_unit::allocate_thread_contexts(int n)
107
1.06k
{
108
1.06k
  assert(thread_contexts==nullptr);
109
110
1.06k
  thread_contexts = new thread_context[n];
111
1.06k
  nThreadContexts = n;
112
1.06k
}
113
114
115
8.37k
image_unit::image_unit() = default;
116
117
118
image_unit::~image_unit()
119
8.37k
{
120
16.7k
  for (size_t i=0;i<slice_units.size();i++) {
121
8.40k
    delete slice_units[i];
122
8.40k
  }
123
124
312k
  for (size_t i=0;i<tasks.size();i++) {
125
304k
    delete tasks[i];
126
304k
  }
127
8.37k
}
128
129
130
base_context::base_context()
131
9.07k
{
132
9.07k
  set_acceleration_functions(de265_acceleration_AUTO);
133
9.07k
}
134
135
136
decoder_context::decoder_context()
137
9.07k
{
138
9.07k
  param_image_allocation_functions = de265_image::default_image_allocation;
139
9.07k
  nal_parser.set_security_limits(&param_security_limits);
140
9.07k
  compute_framedrop_table();
141
9.07k
}
142
143
144
decoder_context::~decoder_context()
145
9.07k
{
146
9.19k
  while (!image_units.empty()) {
147
116
    delete image_units.back();
148
116
    image_units.pop_back();
149
116
  }
150
9.07k
}
151
152
153
void decoder_context::set_image_allocation_functions(de265_image_allocation* allocfunc,
154
                                                     void* userdata)
155
0
{
156
0
  if (allocfunc) {
157
0
    param_image_allocation_functions = *allocfunc;
158
0
    param_image_allocation_userdata  = userdata;
159
0
  }
160
0
  else {
161
0
    assert(false); // actually, it makes no sense to reset the allocation functions
162
163
0
    param_image_allocation_functions = de265_image::default_image_allocation;
164
0
    param_image_allocation_userdata  = nullptr;
165
0
  }
166
0
}
167
168
169
de265_error decoder_context::start_thread_pool(int nThreads)
170
9.07k
{
171
9.07k
  thread_pool_.start(nThreads);
172
173
9.07k
  num_worker_threads = nThreads;
174
175
9.07k
  return DE265_OK;
176
9.07k
}
177
178
179
void decoder_context::stop_thread_pool()
180
9.07k
{
181
9.07k
  if (get_num_worker_threads()>0) {
182
    //flush_thread_pool(&ctx->thread_pool);
183
9.07k
    thread_pool_.stop();
184
9.07k
  }
185
9.07k
}
186
187
188
void decoder_context::reset()
189
0
{
190
0
  if (num_worker_threads>0) {
191
    //flush_thread_pool(&ctx->thread_pool);
192
0
    thread_pool_.stop();
193
0
  }
194
195
  // --------------------------------------------------
196
197
0
  NumPocStCurrBefore = 0;
198
0
  NumPocStCurrAfter = 0;
199
0
  NumPocStFoll = 0;
200
0
  NumPocLtCurr = 0;
201
0
  NumPocLtFoll = 0;
202
0
  nal_unit_type = 0;
203
0
  IdrPicFlag = 0;
204
0
  RapPicFlag = 0;
205
206
0
  img = nullptr;
207
208
  // Drop the back-reference to the previous picture's slice header before the
209
  // DPB is cleared below. dpb.clear() releases the images, which own and free
210
  // their slice_segment_header structs (see de265_image::release()). Leaving
211
  // previous_slice_header pointing into that freed storage lets a following
212
  // dependent slice read from it (slice.cc: '*this = *ctx->previous_slice_header'),
213
  // a heap-use-after-free. This mirrors the in-stream new-picture guard in
214
  // read_slice_NAL(): only a slice header still retained by a live image may
215
  // remain as previous_slice_header.
216
0
  previous_slice_header = nullptr;
217
218
219
  // TODO: remove all pending image_units
220
221
222
  // --- decoded picture buffer ---
223
224
0
  current_image_poc_lsb = -1; // any invalid number
225
0
  first_decoded_picture = true;
226
227
228
  // --- remove all pictures from output queue ---
229
230
  // there was a bug the peek_next_image did not return nullptr on empty output queues.
231
  // This was (indirectly) fixed by recreating the DPB buffer, but it should actually
232
  // be sufficient to clear it like this.
233
  // The error showed while scrubbing the ToS video in VLC.
234
0
  dpb.clear();
235
236
0
  nal_parser.remove_pending_input_data();
237
238
239
0
  while (!image_units.empty()) {
240
0
    delete image_units.back();
241
0
    image_units.pop_back();
242
0
  }
243
244
  // --- start threads again ---
245
246
0
  if (num_worker_threads>0) {
247
    // TODO: need error checking
248
0
    start_thread_pool(num_worker_threads);
249
0
  }
250
0
}
251
252
void base_context::set_acceleration_functions(enum de265_acceleration l)
253
9.07k
{
254
  // fill scalar functions first (so that function table is completely filled)
255
256
9.07k
  init_acceleration_functions_fallback(&acceleration);
257
258
259
  // override functions with optimized variants
260
261
#ifdef HAVE_SSE4_1
262
  if (l>=de265_acceleration_SSE) {
263
    init_acceleration_functions_sse(&acceleration);
264
  }
265
#endif
266
#if HAVE_AVX2
267
  // layered on top of SSE: overrides a few transform kernels (runtime-checked)
268
  if (l>=de265_acceleration_AVX2) {
269
    init_acceleration_functions_avx2(&acceleration);
270
  }
271
#endif
272
#if HAVE_AVX512
273
  // layered on top of AVX2: overrides the 32x32 transform (runtime-checked)
274
  if (l>=de265_acceleration_AVX2) {
275
    init_acceleration_functions_avx512(&acceleration);
276
  }
277
#endif
278
#ifdef HAVE_ARM32
279
  if (l>=de265_acceleration_ARM) {
280
    init_acceleration_functions_arm(&acceleration);
281
  }
282
#endif
283
9.07k
}
284
285
286
void decoder_context::init_thread_context(thread_context* tctx)
287
12.5k
{
288
  // zero scrap memory for coefficient blocks
289
12.5k
  memset(tctx->_coeffBuf, 0, sizeof(tctx->_coeffBuf));  // TODO: check if we can safely remove this
290
291
12.5k
  tctx->currentQG_x = -1;
292
12.5k
  tctx->currentQG_y = -1;
293
294
295
296
  // --- find QPY that was active at the end of the previous slice ---
297
298
  // find the previous CTB in TS order
299
300
12.5k
  const pic_parameter_set& pps = tctx->img->get_pps();
301
12.5k
  const seq_parameter_set& sps = tctx->img->get_sps();
302
303
304
12.5k
  if (tctx->shdr->slice_segment_address > 0) {
305
27
    int prevCtb = pps.scan->CtbAddrTStoRS[ pps.scan->CtbAddrRStoTS[tctx->shdr->slice_segment_address] -1 ];
306
307
27
    int ctbX = prevCtb % sps.PicWidthInCtbsY;
308
27
    int ctbY = prevCtb / sps.PicWidthInCtbsY;
309
310
311
    // take the pixel at the bottom right corner (but consider that the image size might be smaller)
312
313
27
    int x = ((ctbX+1) << sps.Log2CtbSizeY)-1;
314
27
    int y = ((ctbY+1) << sps.Log2CtbSizeY)-1;
315
316
27
    x = std::min(x,sps.pic_width_in_luma_samples-1);
317
27
    y = std::min(y,sps.pic_height_in_luma_samples-1);
318
319
    //printf("READ QPY: %d %d -> %d (should %d)\n",x,y,imgunit->img->get_QPY(x,y), tc.currentQPY);
320
321
    //if (tctx->shdr->dependent_slice_segment_flag) {  // TODO: do we need this condition ?
322
27
    tctx->currentQPY = tctx->img->get_QPY(x,y);
323
      //}
324
27
  }
325
12.5k
}
326
327
328
void decoder_context::add_task_decode_CTB_row(thread_context* tctx,
329
                                              bool firstSliceSubstream,
330
                                              uint16_t ctbRow)
331
5.00k
{
332
5.00k
  thread_task_ctb_row* task = new thread_task_ctb_row;
333
5.00k
  task->firstSliceSubstream = firstSliceSubstream;
334
5.00k
  task->tctx = tctx;
335
5.00k
  task->debug_startCtbRow = ctbRow;
336
5.00k
  tctx->task = task;
337
338
5.00k
  thread_pool_.add_task(task);
339
340
5.00k
  tctx->imgunit->tasks.push_back(task);
341
5.00k
}
342
343
344
void decoder_context::add_task_decode_slice_segment(thread_context* tctx, bool firstSliceSubstream,
345
                                                    uint16_t ctbx, uint16_t ctby)
346
322
{
347
322
  thread_task_slice_segment* task = new thread_task_slice_segment;
348
322
  task->firstSliceSubstream = firstSliceSubstream;
349
322
  task->tctx = tctx;
350
322
  task->debug_startCtbX = ctbx;
351
322
  task->debug_startCtbY = ctby;
352
322
  tctx->task = task;
353
354
322
  thread_pool_.add_task(task);
355
356
322
  tctx->imgunit->tasks.push_back(task);
357
322
}
358
359
360
de265_error decoder_context::read_vps_NAL(bitreader& reader)
361
13.0k
{
362
13.0k
  logdebug(LogHeaders,"---> read VPS\n");
363
364
13.0k
  std::shared_ptr<video_parameter_set> new_vps = std::make_shared<video_parameter_set>();
365
13.0k
  de265_error err = new_vps->read(this,&reader);
366
13.0k
  if (err != DE265_OK) {
367
1.12k
    return err;
368
1.12k
  }
369
370
11.9k
  if (param_vps_headers_fd>=0) {
371
0
    new_vps->dump(param_vps_headers_fd);
372
0
  }
373
374
11.9k
  vps[ new_vps->video_parameter_set_id ] = new_vps;
375
376
11.9k
  return DE265_OK;
377
13.0k
}
378
379
de265_error decoder_context::read_sps_NAL(bitreader& reader)
380
14.2k
{
381
14.2k
  logdebug(LogHeaders,"----> read SPS\n");
382
383
14.2k
  std::shared_ptr<seq_parameter_set> new_sps = std::make_shared<seq_parameter_set>();
384
14.2k
  de265_error err;
385
386
14.2k
  if ((err=new_sps->read(this, &reader)) != DE265_OK) {
387
1.22k
    return err;
388
1.22k
  }
389
390
12.9k
  if (param_sps_headers_fd>=0) {
391
0
    new_sps->dump(param_sps_headers_fd);
392
0
  }
393
394
12.9k
  sps[ new_sps->seq_parameter_set_id ] = new_sps;
395
396
  // Remove the all PPS that referenced the old SPS because parameters may have changed and we do not want to
397
  // get the SPS and PPS parameters (e.g. image size) out of sync.
398
  
399
830k
  for (auto& p : pps) {
400
830k
    if (p && p->seq_parameter_set_id == new_sps->seq_parameter_set_id) {
401
3.78k
      p = nullptr;
402
3.78k
    }
403
830k
  }
404
405
12.9k
  return DE265_OK;
406
14.2k
}
407
408
de265_error decoder_context::read_pps_NAL(bitreader& reader)
409
14.2k
{
410
14.2k
  logdebug(LogHeaders,"----> read PPS\n");
411
412
14.2k
  std::shared_ptr<pic_parameter_set> new_pps = std::make_shared<pic_parameter_set>();
413
414
14.2k
  bool success = new_pps->read(&reader,this);
415
14.2k
  if (!success) {
416
1.82k
    return DE265_WARNING_PPS_HEADER_INVALID;
417
1.82k
  }
418
419
12.3k
  if (param_pps_headers_fd>=0) {
420
0
    new_pps->dump(param_pps_headers_fd);
421
0
  }
422
423
12.3k
  pps[ (int)new_pps->pic_parameter_set_id ] = new_pps;
424
425
12.3k
  return DE265_OK;
426
14.2k
}
427
428
de265_error decoder_context::read_sei_NAL(bitreader& reader, bool suffix)
429
39
{
430
39
  logdebug(LogHeaders,"----> read SEI\n");
431
432
39
  sei_message sei;
433
434
  //push_current_picture_to_output_queue();
435
436
39
  de265_error err = DE265_OK;
437
438
39
  if ((err=read_sei(&reader,&sei, suffix, current_sps.get())) == DE265_OK) {
439
38
    dump_sei(&sei, current_sps.get());
440
441
38
    if (image_units.empty()==false && suffix) {
442
1
      uint32_t max_SEI_messages = param_security_limits.max_SEI_messages;
443
1
      if (max_SEI_messages != 0 &&
444
1
          image_units.back()->suffix_SEIs.size() >= max_SEI_messages) {
445
        // too many SEI messages for this access unit -> drop to bound memory usage
446
0
        add_warning(DE265_WARNING_MAX_NUMBER_OF_SEI_MESSAGES_EXCEEDED, false);
447
0
        return DE265_WARNING_MAX_NUMBER_OF_SEI_MESSAGES_EXCEEDED;
448
0
      }
449
450
1
      image_units.back()->suffix_SEIs.push_back(sei);
451
1
    }
452
38
  }
453
1
  else {
454
1
    add_warning(err, false);
455
1
  }
456
457
39
  return err;
458
39
}
459
460
de265_error decoder_context::read_eos_NAL(bitreader& reader)
461
0
{
462
0
  FirstAfterEndOfSequenceNAL = true;
463
0
  return DE265_OK;
464
0
}
465
466
bool decoder_context::slice_segment_order_is_valid(image_unit* imgunit,
467
                                                   const slice_segment_header* shdr)
468
8.41k
{
469
  // Nothing to compare against for the first slice segment of the picture.
470
8.41k
  if (imgunit->slice_units.empty() || imgunit->img == nullptr) {
471
8.37k
    return true;
472
8.37k
  }
473
474
41
  de265_image* img = imgunit->img;
475
41
  const pic_parameter_set& pps = img->get_pps();
476
41
  if (!pps.scan) {
477
0
    return true;
478
0
  }
479
480
41
  const std::vector<uint32_t>& RStoTS = pps.scan->CtbAddrRStoTS;
481
482
41
  uint32_t prevAddr = imgunit->slice_units.back()->shdr->slice_segment_address;
483
41
  uint32_t thisAddr = shdr->slice_segment_address;
484
485
41
  if (prevAddr >= RStoTS.size() || thisAddr >= RStoTS.size()) {
486
0
    add_warning(DE265_WARNING_SLICE_SEGMENT_ADDRESS_INVALID, false);
487
0
    img->integrity = INTEGRITY_DECODING_ERRORS;
488
0
    return false;
489
0
  }
490
491
  // H.265 7.4.2.4.5: the slice segments of a coded picture shall be ordered by
492
  // increasing tile-scan address of their first CTB, and (7.4.7.1) no two slice
493
  // segments of a picture share a slice_segment_address. A slice segment that
494
  // repeats or goes back to an earlier address would re-decode CTBs that were
495
  // already decoded. In WPP mode the progress of those CTBs is already marked
496
  // as finished, so the row tasks of the offending slice segment would not wait
497
  // for the row above and would race with each other on the CTB metadata and
498
  // the reconstructed pixels. Drop such slice segments.
499
41
  if (RStoTS[thisAddr] <= RStoTS[prevAddr]) {
500
11
    add_warning(DE265_WARNING_SLICE_SEGMENT_ADDRESS_NOT_INCREASING, false);
501
11
    img->integrity = INTEGRITY_DECODING_ERRORS;
502
11
    return false;
503
11
  }
504
505
30
  return true;
506
41
}
507
508
509
de265_error decoder_context::read_slice_NAL(bitreader& reader, std::unique_ptr<NAL_unit> nal, nal_header& nal_hdr)
510
9.73k
{
511
9.73k
  logdebug(LogHeaders,"---> read slice segment header\n");
512
513
514
  // --- read slice header ---
515
516
9.73k
  slice_segment_header* shdr = new slice_segment_header;
517
9.73k
  bool continueDecoding;
518
9.73k
  de265_error err = shdr->read(&reader,this, &continueDecoding);
519
9.73k
  if (!continueDecoding) {
520
1.15k
    if (img) { img->integrity = INTEGRITY_NOT_DECODED; }
521
1.15k
    nal_parser.free_NAL_unit(std::move(nal));
522
1.15k
    delete shdr;
523
1.15k
    return err;
524
1.15k
  }
525
526
8.57k
  if (param_slice_headers_fd>=0) {
527
0
    shdr->dump_slice_segment_header(this, param_slice_headers_fd);
528
0
  }
529
530
531
8.57k
  if (process_slice_segment_header(shdr, &err, nal->pts, &nal_hdr, nal->user_data) == false)
532
165
    {
533
165
      if (img!=nullptr) img->integrity = INTEGRITY_NOT_DECODED;
534
165
      nal_parser.free_NAL_unit(std::move(nal));
535
165
      delete shdr;
536
165
      return err;
537
165
    }
538
539
8.40k
  reader.skip_bits(1); // TODO: why?
540
8.40k
  reader.prepare_for_CABAC();
541
542
543
  // modify entry_point_offsets
544
545
8.40k
  uint32_t headerLength = reader.data - nal->data();
546
13.2k
  for (uint32_t i=0;i<shdr->num_entry_point_offsets;i++) {
547
4.82k
    uint32_t skipped = nal->num_skipped_bytes_before(shdr->entry_point_offset[i],
548
4.82k
                                                     headerLength);
549
4.82k
    if (skipped > shdr->entry_point_offset[i]) {
550
0
      add_warning(DE265_WARNING_SLICEHEADER_INVALID, false);
551
0
      nal_parser.free_NAL_unit(std::move(nal));
552
0
      delete shdr;
553
0
      return DE265_ERROR_CODED_PARAMETER_OUT_OF_RANGE;
554
0
    }
555
4.82k
    shdr->entry_point_offset[i] -= skipped;
556
4.82k
  }
557
558
  // --- start a new image if this is the first slice ---
559
560
8.40k
  if (shdr->first_slice_segment_in_pic_flag) {
561
8.36k
    image_unit* imgunit = new image_unit;
562
8.36k
    imgunit->img = this->img;
563
8.36k
    image_units.push_back(imgunit);
564
565
    // A new picture starts here. Drop the reference to the previous picture's
566
    // slice header, whose storage may be released independently of this decoder
567
    // state. Dependent slices only ever reference a preceding slice header
568
    // within the same picture, which is set below as slices are retained.
569
8.36k
    previous_slice_header = nullptr;
570
8.36k
  }
571
572
573
  // --- add slice to current picture ---
574
575
8.40k
  if ( ! image_units.empty() &&
576
8.41k
       slice_segment_order_is_valid(image_units.back(), shdr) ) {
577
578
    // Hand the slice header to the picture (which takes ownership and frees it
579
    // on release). Only do this when there is an active image unit to decode
580
    // the slice; otherwise the header would be retained on img->slices forever,
581
    // which a crafted stream of non-first slice NALs can exploit to grow memory
582
    // without bound.
583
8.40k
    this->img->add_slice_segment_header(shdr);
584
585
    // The header is now owned by the image and stays alive at least until the
586
    // image is released, so it is safe for a following dependent slice to copy
587
    // from it. Only retained headers may become 'previous_slice_header'.
588
8.40k
    previous_slice_header = shdr;
589
590
8.40k
    slice_unit* sliceunit = new slice_unit(this);
591
8.40k
    sliceunit->nal = std::move(nal);
592
8.40k
    sliceunit->shdr = shdr;
593
8.40k
    sliceunit->reader = reader;
594
595
8.40k
    sliceunit->flush_reorder_buffer = flush_reorder_buffer_at_this_frame;
596
597
598
8.40k
    image_units.back()->slice_units.push_back(sliceunit);
599
8.40k
  }
600
3
  else {
601
3
    nal_parser.free_NAL_unit(std::move(nal));
602
3
    delete shdr;
603
3
  }
604
605
8.40k
  bool did_work;
606
8.40k
  err = decode_some(&did_work);
607
608
8.40k
  return DE265_OK;
609
8.40k
}
610
611
612
template <class T> void pop_front(std::vector<T>& vec)
613
8.26k
{
614
8.37k
  for (size_t i=1;i<vec.size();i++)
615
117
    vec[i-1] = vec[i];
616
617
8.26k
  vec.pop_back();
618
8.26k
}
619
620
621
de265_error decoder_context::decode_some(bool* did_work)
622
9.09k
{
623
9.09k
  de265_error err = DE265_OK;
624
625
9.09k
  *did_work = false;
626
627
9.09k
  if (image_units.empty()) { return DE265_OK; }  // nothing to do
628
629
630
  // decode something if there is work to do
631
632
9.09k
  if ( ! image_units.empty() ) { // && ! image_units[0]->slice_units.empty() ) {
633
634
9.08k
    image_unit* imgunit = image_units[0];
635
9.08k
    slice_unit* sliceunit = imgunit->get_next_unprocessed_slice_segment();
636
637
9.08k
    if (sliceunit != nullptr) {
638
639
      //pop_front(imgunit->slice_units);
640
641
8.28k
      if (sliceunit->flush_reorder_buffer) {
642
8.03k
        dpb.flush_reorder_buffer();
643
8.03k
      }
644
645
8.28k
      *did_work = true;
646
647
      //err = decode_slice_unit_sequential(imgunit, sliceunit);
648
8.28k
      err = decode_slice_unit_parallel(imgunit, sliceunit);
649
8.28k
      if (err) {
650
56
        return err;
651
56
      }
652
653
      //delete sliceunit;
654
8.28k
    }
655
9.08k
  }
656
657
658
659
  // if we decoded all slices of the current image and there will not
660
  // be added any more slices to the image, output the image
661
662
9.03k
  if ( ( image_units.size()>=2 && image_units[0]->all_slice_segments_processed()) ||
663
8.92k
       ( image_units.size()>=1 && image_units[0]->all_slice_segments_processed() &&
664
8.92k
         nal_parser.number_of_NAL_units_pending()==0 &&
665
8.26k
         (nal_parser.is_end_of_stream() || nal_parser.is_end_of_frame()) )) {
666
667
8.26k
    image_unit* imgunit = image_units[0];
668
669
8.26k
    *did_work=true;
670
671
672
    // mark all CTBs as decoded even if they are not, because faulty input
673
    // streams could miss part of the picture
674
    // TODO: this will not work when slice decoding is parallel to post-filtering,
675
    // so we will have to replace this with keeping track of which CTB should have
676
    // been decoded (but aren't because of the input stream being faulty)
677
678
8.26k
    imgunit->img->mark_all_CTB_progress(CTB_PROGRESS_PREFILTER);
679
680
681
682
    // run post-processing filters (deblocking & SAO)
683
684
8.26k
    if (img->decctx->num_worker_threads)
685
8.26k
      run_postprocessing_filters_parallel(imgunit);
686
0
    else
687
0
      run_postprocessing_filters_sequential(imgunit->img);
688
689
    // process suffix SEIs
690
691
8.26k
    for (size_t i=0;i<imgunit->suffix_SEIs.size();i++) {
692
1
      const sei_message& sei = imgunit->suffix_SEIs[i];
693
694
1
      err = process_sei(&sei, imgunit->img);
695
1
      if (err != DE265_OK)
696
0
        break;
697
1
    }
698
699
700
8.26k
    push_picture_to_output_queue(imgunit);
701
702
    // remove just decoded image unit from queue
703
704
8.26k
    delete imgunit;
705
706
8.26k
    pop_front(image_units);
707
8.26k
  }
708
709
9.03k
  return err;
710
9.09k
}
711
712
713
de265_error decoder_context::decode_slice_unit_sequential(image_unit* imgunit,
714
                                                          slice_unit* sliceunit)
715
7.20k
{
716
7.20k
  de265_error err = DE265_OK;
717
718
  /*
719
  printf("decode slice POC=%d addr=%d, img=%p\n",
720
         sliceunit->shdr->slice_pic_order_cnt_lsb,
721
         sliceunit->shdr->slice_segment_address,
722
         imgunit->img);
723
  */
724
725
7.20k
  remove_images_from_dpb(sliceunit->shdr->RemoveReferencesList);
726
727
7.20k
  if (sliceunit->shdr->slice_segment_address >= imgunit->img->get_pps().scan->CtbAddrRStoTS.size()) {
728
0
    return DE265_ERROR_CTB_OUTSIDE_IMAGE_AREA;
729
0
  }
730
731
732
7.20k
  thread_context tctx;
733
734
7.20k
  tctx.shdr = sliceunit->shdr;
735
7.20k
  tctx.img  = imgunit->img;
736
7.20k
  tctx.decctx = this;
737
7.20k
  tctx.imgunit = imgunit;
738
7.20k
  tctx.sliceunit= sliceunit;
739
7.20k
  tctx.CtbAddrInTS = imgunit->img->get_pps().scan->CtbAddrRStoTS[tctx.shdr->slice_segment_address];
740
7.20k
  tctx.task = nullptr;
741
742
7.20k
  init_thread_context(&tctx);
743
744
7.20k
  if (sliceunit->reader.bytes_remaining <= 0) {
745
14
    return DE265_ERROR_PREMATURE_END_OF_SLICE;
746
14
  }
747
748
7.19k
  tctx.cabac_decoder.init(sliceunit->reader.data,
749
7.19k
                         sliceunit->reader.bytes_remaining);
750
751
  // alloc CABAC-model array if entropy_coding_sync is enabled
752
753
7.19k
  if (imgunit->img->get_pps().entropy_coding_sync_enabled_flag &&
754
0
      sliceunit->shdr->first_slice_segment_in_pic_flag) {
755
0
    imgunit->ctx_models.resize( (img->get_sps().PicHeightInCtbsY-1) ); //* CONTEXT_MODEL_TABLE_LENGTH );
756
0
    imgunit->StatCoeff_models.assign( (img->get_sps().PicHeightInCtbsY-1), {{0,0,0,0}} );
757
0
  }
758
759
7.19k
  sliceunit->nThreads=1;
760
761
7.19k
  err=read_slice_segment_data(&tctx);
762
763
7.19k
  sliceunit->finished_threads.set_progress(1);
764
765
7.19k
  return err;
766
7.20k
}
767
768
769
void decoder_context::mark_whole_slice_as_processed(image_unit* imgunit,
770
                                                    slice_unit* sliceunit,
771
                                                    int progress)
772
8.31k
{
773
  //printf("mark whole slice\n");
774
775
776
  // mark all CTBs upto the next slice segment as processed
777
778
8.31k
  slice_unit* nextSegment = imgunit->get_next_slice_segment(sliceunit);
779
8.31k
  if (nextSegment) {
780
    /*
781
    printf("mark whole slice between %d and %d\n",
782
           sliceunit->shdr->slice_segment_address,
783
           nextSegment->shdr->slice_segment_address);
784
    */
785
786
29
    for (uint32_t ctb=sliceunit->shdr->slice_segment_address;
787
1.19k
         ctb < nextSegment->shdr->slice_segment_address;
788
1.17k
         ctb++)
789
1.17k
      {
790
1.17k
        if (ctb >= imgunit->img->number_of_ctbs())
791
0
          break;
792
793
1.17k
        imgunit->img->ctb_progress[ctb].set_progress(progress);
794
1.17k
      }
795
29
  }
796
8.31k
}
797
798
799
de265_error decoder_context::decode_slice_unit_parallel(image_unit* imgunit,
800
                                                        slice_unit* sliceunit)
801
8.27k
{
802
8.27k
  de265_error err = DE265_OK;
803
804
8.27k
  remove_images_from_dpb(sliceunit->shdr->RemoveReferencesList);
805
806
  /*
807
  printf("-------- decode --------\n");
808
  printf("IMAGE UNIT %p\n",imgunit);
809
  sliceunit->shdr->dump_slice_segment_header(sliceunit->ctx, 1);
810
  imgunit->dump_slices();
811
  */
812
813
8.27k
  de265_image* img = imgunit->img;
814
8.27k
  const pic_parameter_set& pps = img->get_pps();
815
816
8.27k
  sliceunit->state = slice_unit::InProgress;
817
818
8.27k
  bool use_WPP = (img->decctx->num_worker_threads > 0 &&
819
8.28k
                  pps.entropy_coding_sync_enabled_flag);
820
821
8.27k
  bool use_tiles = (img->decctx->num_worker_threads > 0 &&
822
8.28k
                    pps.tiles_enabled_flag);
823
824
825
  // TODO: remove this warning later when we do frame-parallel decoding
826
8.27k
  if (img->decctx->num_worker_threads > 0 &&
827
8.27k
      pps.entropy_coding_sync_enabled_flag == false &&
828
7.46k
      pps.tiles_enabled_flag == false) {
829
830
7.20k
    img->decctx->add_warning(DE265_WARNING_NO_WPP_CANNOT_USE_MULTITHREADING, true);
831
7.20k
  }
832
833
834
  // If this is the first slice segment, mark all CTBs before this as processed
835
  // (the real first slice segment could be missing).
836
837
8.27k
  if (imgunit->is_first_slice_segment(sliceunit)) {
838
8.25k
    slice_segment_header* shdr = sliceunit->shdr;
839
8.25k
    int firstCTB = shdr->slice_segment_address;
840
841
8.25k
    for (int ctb=0;ctb<firstCTB;ctb++) {
842
      //printf("mark pre progress %d\n",ctb);
843
0
      img->ctb_progress[ctb].set_progress(CTB_PROGRESS_PREFILTER);
844
0
    }
845
8.25k
  }
846
847
848
  // if there is a previous slice that has been completely decoded,
849
  // mark all CTBs until the start of this slice as completed
850
851
  //printf("this slice: %p\n",sliceunit);
852
8.27k
  slice_unit* prevSlice = imgunit->get_prev_slice_segment(sliceunit);
853
  //if (prevSlice) printf("prev slice state: %d\n",prevSlice->state);
854
8.27k
  if (prevSlice && prevSlice->state == slice_unit::Decoded) {
855
29
    mark_whole_slice_as_processed(imgunit,prevSlice,CTB_PROGRESS_PREFILTER);
856
29
  }
857
858
859
  // TODO: even though we cannot split this into several tasks, we should run it
860
  // as a background thread
861
8.27k
  if (!use_WPP && !use_tiles) {
862
    //printf("SEQ\n");
863
7.21k
    err = decode_slice_unit_sequential(imgunit, sliceunit);
864
7.21k
    sliceunit->state = slice_unit::Decoded;
865
7.21k
    mark_whole_slice_as_processed(imgunit,sliceunit,CTB_PROGRESS_PREFILTER);
866
7.21k
    return err;
867
7.21k
  }
868
869
870
1.06k
  if (use_WPP && use_tiles) {
871
    // TODO: this is not allowed ... output some warning or error
872
873
7
    return DE265_WARNING_PPS_HEADER_INVALID;
874
7
  }
875
876
877
1.05k
  if (use_WPP) {
878
    //printf("WPP\n");
879
811
    err = decode_slice_unit_WPP(imgunit, sliceunit);
880
811
    sliceunit->state = slice_unit::Decoded;
881
811
    mark_whole_slice_as_processed(imgunit,sliceunit,CTB_PROGRESS_PREFILTER);
882
811
    return err;
883
811
  }
884
254
  else if (use_tiles) {
885
    //printf("TILE\n");
886
254
    err = decode_slice_unit_tiles(imgunit, sliceunit);
887
254
    sliceunit->state = slice_unit::Decoded;
888
254
    mark_whole_slice_as_processed(imgunit,sliceunit,CTB_PROGRESS_PREFILTER);
889
254
    return err;
890
254
  }
891
892
18.4E
  assert(false);
893
0
  return err;
894
18.4E
}
895
896
897
de265_error decoder_context::decode_slice_unit_WPP(image_unit* imgunit,
898
                                                   slice_unit* sliceunit)
899
811
{
900
811
  de265_error err = DE265_OK;
901
902
811
  de265_image* img = imgunit->img;
903
811
  slice_segment_header* shdr = sliceunit->shdr;
904
811
  const pic_parameter_set& pps = img->get_pps();
905
906
811
  uint16_t nRows = shdr->num_entry_point_offsets +1;
907
811
  uint16_t ctbsWidth = img->get_sps().PicWidthInCtbsY;
908
909
910
811
  assert(img->num_threads_active() == 0);
911
912
913
  // reserve space to store entropy coding context models for each CTB row
914
915
811
  if (shdr->first_slice_segment_in_pic_flag) {
916
    // reserve space for nRows-1 because we don't need to save the CABAC model in the last CTB row
917
796
    imgunit->ctx_models.resize( (img->get_sps().PicHeightInCtbsY-1) ); //* CONTEXT_MODEL_TABLE_LENGTH );
918
796
    imgunit->StatCoeff_models.assign( (img->get_sps().PicHeightInCtbsY-1), {{0,0,0,0}} );
919
796
  }
920
921
922
811
  sliceunit->allocate_thread_contexts(nRows);
923
924
925
  // first CTB in this slice
926
811
  uint32_t ctbAddrRS = shdr->slice_segment_address;
927
811
  uint16_t ctbRow    = ctbAddrRS / ctbsWidth;
928
929
811
  if (ctbRow + nRows > img->get_sps().PicHeightInCtbsY) {
930
1
    return DE265_WARNING_SLICEHEADER_INVALID;
931
1
  }
932
933
  // Reset the decoding progress of all CTBs that the row tasks of this slice
934
  // segment are going to decode (from its first CTB to the end of its last
935
  // CTB row). Their progress may already be marked as finished, e.g. by a
936
  // preceding slice segment whose entry points claimed more rows than its
937
  // data covered, because a row task marks the rest of its row as finished
938
  // when it fails. Stale progress would let the row tasks of this slice
939
  // segment skip waiting for the row above and race with each other on the
940
  // CTB metadata and the reconstructed pixels. No task is running on the
941
  // image at this point (asserted above), so nobody can be waiting on the
942
  // CTBs that are reset here.
943
810
  {
944
810
    uint32_t endCtb = std::min<uint32_t>((uint32_t)(ctbRow + nRows) * ctbsWidth,
945
810
                                         img->number_of_ctbs());
946
58.9k
    for (uint32_t ctb = ctbAddrRS; ctb < endCtb; ctb++) {
947
58.1k
      img->ctb_progress[ctb].reset(CTB_PROGRESS_NONE);
948
58.1k
    }
949
810
  }
950
951
5.81k
  for (uint16_t entryPt=0;entryPt<nRows;entryPt++) {
952
    // entry points other than the first start at CTB rows
953
5.03k
    if (entryPt>0) {
954
4.22k
      ctbRow++;
955
4.22k
      ctbAddrRS = ctbRow * ctbsWidth;
956
4.22k
    }
957
810
    else if (nRows>1 && (ctbAddrRS % ctbsWidth) != 0) {
958
      // If slice segment consists of several WPP rows, each of them
959
      // has to start at a row.
960
961
      //printf("does not start at start\n");
962
963
1
      err = DE265_WARNING_SLICEHEADER_INVALID;
964
1
      break;
965
1
    }
966
967
968
    // prepare thread context
969
970
5.03k
    thread_context* tctx = sliceunit->get_thread_context(entryPt);
971
972
5.03k
    tctx->shdr    = shdr;
973
5.03k
    tctx->decctx  = img->decctx;
974
5.03k
    tctx->img     = img;
975
5.03k
    tctx->imgunit = imgunit;
976
5.03k
    tctx->sliceunit= sliceunit;
977
978
5.03k
    if (ctbAddrRS >= pps.scan->CtbAddrRStoTS.size()) {
979
0
      err = DE265_WARNING_SLICEHEADER_INVALID;
980
0
      break;
981
0
    }
982
5.03k
    tctx->CtbAddrInTS = pps.scan->CtbAddrRStoTS[ctbAddrRS];
983
984
5.03k
    init_thread_context(tctx);
985
986
987
    // init CABAC
988
989
5.03k
    int dataStartIndex;
990
5.03k
    if (entryPt==0) { dataStartIndex=0; }
991
4.22k
    else            { dataStartIndex=shdr->entry_point_offset[entryPt-1]; }
992
993
5.03k
    int dataEnd;
994
5.03k
    if (entryPt==nRows-1) dataEnd = sliceunit->reader.bytes_remaining;
995
4.25k
    else                  dataEnd = shdr->entry_point_offset[entryPt];
996
997
5.03k
    if (dataStartIndex<0 || dataEnd>sliceunit->reader.bytes_remaining ||
998
5.01k
        dataEnd <= dataStartIndex) {
999
      //printf("WPP premature end\n");
1000
31
      err = DE265_ERROR_PREMATURE_END_OF_SLICE;
1001
31
      break;
1002
31
    }
1003
1004
5.00k
    tctx->cabac_decoder.init(&sliceunit->reader.data[dataStartIndex],
1005
5.00k
                             dataEnd-dataStartIndex);
1006
1007
    // add task
1008
1009
    //printf("start task for ctb-row: %d\n",ctbRow);
1010
5.00k
    img->thread_start(1);
1011
5.00k
    sliceunit->nThreads++;
1012
5.00k
    add_task_decode_CTB_row(tctx, entryPt==0, ctbRow);
1013
5.00k
  }
1014
1015
#if 0
1016
  for (;;) {
1017
    printf("q:%d r:%d b:%d f:%d\n",
1018
           img->nThreadsQueued,
1019
           img->nThreadsRunning,
1020
           img->nThreadsBlocked,
1021
           img->nThreadsFinished);
1022
1023
    if (img->debug_is_completed()) break;
1024
1025
    usleep(1000);
1026
  }
1027
#endif
1028
1029
810
  img->wait_for_completion();
1030
1031
5.81k
  for (size_t i=0;i<imgunit->tasks.size();i++)
1032
5.00k
    delete imgunit->tasks[i];
1033
810
  imgunit->tasks.clear();
1034
1035
810
  return err;
1036
811
}
1037
1038
de265_error decoder_context::decode_slice_unit_tiles(image_unit* imgunit,
1039
                                                     slice_unit* sliceunit)
1040
254
{
1041
254
  de265_error err = DE265_OK;
1042
1043
254
  de265_image* img = imgunit->img;
1044
254
  slice_segment_header* shdr = sliceunit->shdr;
1045
254
  const pic_parameter_set& pps = img->get_pps();
1046
1047
254
  uint16_t nTiles = shdr->num_entry_point_offsets +1;
1048
254
  uint16_t ctbsWidth = img->get_sps().PicWidthInCtbsY;
1049
1050
1051
254
  assert(img->num_threads_active() == 0);
1052
1053
254
  sliceunit->allocate_thread_contexts(nTiles);
1054
1055
1056
  // first CTB in this slice
1057
254
  uint32_t ctbAddrRS = shdr->slice_segment_address;
1058
1059
  // pps.scan->TileIdRS and pps.scan->CtbAddrRStoTS are both sized to PicSizeInCtbsY in
1060
  // set_derived_values(), so one bound covers both accesses below.
1061
254
  if (ctbAddrRS >= pps.scan->CtbAddrRStoTS.size()) {
1062
0
    return DE265_WARNING_SLICEHEADER_INVALID;
1063
0
  }
1064
254
  int tileID = pps.scan->TileIdRS[ctbAddrRS];
1065
1066
576
  for (uint16_t entryPt=0;entryPt<nTiles;entryPt++) {
1067
    // entry points other than the first start at tile beginnings
1068
324
    if (entryPt>0) {
1069
70
      tileID++;
1070
1071
70
      if (tileID >= pps.num_tile_columns * pps.num_tile_rows) {
1072
0
        err = DE265_WARNING_SLICEHEADER_INVALID;
1073
0
        break;
1074
0
      }
1075
1076
70
      uint16_t ctbX = pps.colBd[tileID % pps.num_tile_columns];
1077
70
      uint16_t ctbY = pps.rowBd[tileID / pps.num_tile_columns];
1078
70
      ctbAddrRS = ctbY * ctbsWidth + ctbX;
1079
1080
70
      if (ctbAddrRS >= pps.scan->CtbAddrRStoTS.size()) {
1081
0
        err = DE265_WARNING_SLICEHEADER_INVALID;
1082
0
        break;
1083
0
      }
1084
70
    }
1085
1086
    // set thread context
1087
1088
324
    thread_context* tctx = sliceunit->get_thread_context(entryPt);
1089
1090
324
    tctx->shdr   = shdr;
1091
324
    tctx->decctx = img->decctx;
1092
324
    tctx->img    = img;
1093
324
    tctx->imgunit = imgunit;
1094
324
    tctx->sliceunit= sliceunit;
1095
324
    tctx->CtbAddrInTS = pps.scan->CtbAddrRStoTS[ctbAddrRS];
1096
1097
324
    init_thread_context(tctx);
1098
1099
1100
    // init CABAC
1101
1102
324
    int dataStartIndex;
1103
324
    if (entryPt==0) { dataStartIndex=0; }
1104
70
    else            { dataStartIndex=shdr->entry_point_offset[entryPt-1]; }
1105
1106
324
    int dataEnd;
1107
324
    if (entryPt==nTiles-1) dataEnd = sliceunit->reader.bytes_remaining;
1108
71
    else                   dataEnd = shdr->entry_point_offset[entryPt];
1109
1110
324
    if (dataStartIndex<0 || dataEnd>sliceunit->reader.bytes_remaining ||
1111
323
        dataEnd <= dataStartIndex) {
1112
2
      err = DE265_ERROR_PREMATURE_END_OF_SLICE;
1113
2
      break;
1114
2
    }
1115
1116
322
    tctx->cabac_decoder.init(&sliceunit->reader.data[dataStartIndex],
1117
322
                             dataEnd-dataStartIndex);
1118
1119
    // add task
1120
1121
    //printf("add tiles thread\n");
1122
322
    img->thread_start(1);
1123
322
    sliceunit->nThreads++;
1124
322
    add_task_decode_slice_segment(tctx, entryPt==0,
1125
322
                                  static_cast<uint16_t>(ctbAddrRS % ctbsWidth),
1126
322
                                  static_cast<uint16_t>(ctbAddrRS / ctbsWidth));
1127
322
  }
1128
1129
254
  img->wait_for_completion();
1130
1131
576
  for (size_t i=0;i<imgunit->tasks.size();i++)
1132
322
    delete imgunit->tasks[i];
1133
254
  imgunit->tasks.clear();
1134
1135
254
  return err;
1136
254
}
1137
1138
1139
// Ownership: decode_NAL() receives the NAL by moved-in unique_ptr and releases
1140
// it on every return path. Parameter-set, SEI and discarded NALs are returned to
1141
// the pool directly here; slice NALs are moved into read_slice_NAL(), which
1142
// either releases the NAL or moves it into a slice_unit that owns it for the rest
1143
// of the image_unit's lifetime. Because ownership is a unique_ptr, the NAL cannot
1144
// be released twice.
1145
de265_error decoder_context::decode_NAL(std::unique_ptr<NAL_unit> nal)
1146
52.4k
{
1147
  //return decode_NAL_OLD(nal);
1148
1149
52.4k
  decoder_context* ctx = this;
1150
1151
52.4k
  de265_error err = DE265_OK;
1152
1153
52.4k
  bitreader reader(nal->data(), nal->size());
1154
1155
52.4k
  nal_header nal_hdr;
1156
52.4k
  err = nal_hdr.read(&reader);
1157
52.4k
  if (err != DE265_OK) {
1158
67
    nal_parser.free_NAL_unit(std::move(nal));
1159
67
    return err;
1160
67
  }
1161
52.3k
  ctx->process_nal_hdr(&nal_hdr);
1162
1163
52.3k
  if (nal_hdr.nuh_layer_id > 0) {
1164
    // Discard all NAL units with nuh_layer_id > 0
1165
    // These will have to be handled by an SHVC decoder.
1166
1.25k
    nal_parser.free_NAL_unit(std::move(nal));
1167
1.25k
    return DE265_OK;
1168
1.25k
  }
1169
1170
51.0k
  loginfo(LogHighlevel,"NAL: 0x%x 0x%x -  unit type:%s temporal id:%d\n",
1171
51.0k
          nal->data()[0], nal->data()[1],
1172
51.0k
          get_NAL_name(nal_hdr.nal_unit_type),
1173
51.0k
          nal_hdr.nuh_temporal_id);
1174
1175
  /*
1176
    printf("NAL: 0x%x 0x%x -  unit type:%s temporal id:%d\n",
1177
    nal->data()[0], nal->data()[1],
1178
    get_NAL_name(nal_hdr.nal_unit_type),
1179
    nal_hdr.nuh_temporal_id);
1180
  */
1181
1182
  // throw away NALs from higher TIDs than currently selected
1183
  // TODO: better online switching of HighestTID
1184
1185
  //printf("hTid: %d\n", current_HighestTid);
1186
1187
51.0k
  if (nal_hdr.nuh_temporal_id > current_HighestTid) {
1188
7
    nal_parser.free_NAL_unit(std::move(nal));
1189
7
    return DE265_OK;
1190
7
  }
1191
1192
1193
51.0k
  if (nal_hdr.nal_unit_type<32) {
1194
9.73k
    err = read_slice_NAL(reader, std::move(nal), nal_hdr);
1195
9.73k
  }
1196
41.3k
  else switch (nal_hdr.nal_unit_type) {
1197
13.0k
    case NAL_UNIT_VPS_NUT:
1198
13.0k
      err = read_vps_NAL(reader);
1199
13.0k
      nal_parser.free_NAL_unit(std::move(nal));
1200
13.0k
      break;
1201
1202
14.2k
    case NAL_UNIT_SPS_NUT:
1203
14.2k
      err = read_sps_NAL(reader);
1204
14.2k
      nal_parser.free_NAL_unit(std::move(nal));
1205
14.2k
      break;
1206
1207
14.2k
    case NAL_UNIT_PPS_NUT:
1208
14.2k
      err = read_pps_NAL(reader);
1209
14.2k
      nal_parser.free_NAL_unit(std::move(nal));
1210
14.2k
      break;
1211
1212
32
    case NAL_UNIT_PREFIX_SEI_NUT:
1213
39
    case NAL_UNIT_SUFFIX_SEI_NUT:
1214
39
      err = read_sei_NAL(reader, nal_hdr.nal_unit_type==NAL_UNIT_SUFFIX_SEI_NUT);
1215
39
      nal_parser.free_NAL_unit(std::move(nal));
1216
39
      break;
1217
1218
7
    case NAL_UNIT_EOS_NUT:
1219
7
      ctx->FirstAfterEndOfSequenceNAL = true;
1220
7
      nal_parser.free_NAL_unit(std::move(nal));
1221
7
      break;
1222
1223
51
    default:
1224
51
      nal_parser.free_NAL_unit(std::move(nal));
1225
51
      break;
1226
41.3k
    }
1227
1228
51.3k
  return err;
1229
51.0k
}
1230
1231
1232
de265_error decoder_context::decode(int* more)
1233
95.1k
{
1234
95.1k
  decoder_context* ctx = this;
1235
1236
  // if the stream has ended, and no more NALs are to be decoded, flush all pictures
1237
1238
95.1k
  if (ctx->nal_parser.get_NAL_queue_length() == 0 &&
1239
42.6k
      (ctx->nal_parser.is_end_of_stream() || ctx->nal_parser.is_end_of_frame()) &&
1240
42.6k
      ctx->image_units.empty()) {
1241
1242
    // flush all pending pictures into output queue
1243
1244
    // ctx->push_current_picture_to_output_queue(); // TODO: not with new queue
1245
42.0k
    ctx->dpb.flush_reorder_buffer();
1246
1247
42.0k
    if (more) { *more = ctx->dpb.num_pictures_in_output_queue(); }
1248
1249
42.0k
    return DE265_OK;
1250
42.0k
  }
1251
1252
1253
  // if NAL-queue is empty, we need more data
1254
  // -> input stalled
1255
1256
53.1k
  if (ctx->nal_parser.is_end_of_stream() == false &&
1257
0
      ctx->nal_parser.is_end_of_frame() == false &&
1258
0
      ctx->nal_parser.get_NAL_queue_length() == 0) {
1259
0
    if (more) { *more=1; }
1260
1261
0
    return DE265_ERROR_WAITING_FOR_INPUT_DATA;
1262
0
  }
1263
1264
1265
  // when there are no free image buffers in the DPB, pause decoding
1266
  // -> output stalled
1267
1268
53.1k
  if (!ctx->dpb.has_free_dpb_picture(false)) {
1269
0
    if (more) *more = 1;
1270
0
    return DE265_ERROR_IMAGE_BUFFER_FULL;
1271
0
  }
1272
1273
1274
  // decode one NAL from the queue
1275
1276
53.1k
  de265_error err = DE265_OK;
1277
53.1k
  bool did_work = false;
1278
1279
53.1k
  if (ctx->nal_parser.get_NAL_queue_length()) { // number_of_NAL_units_pending()) {
1280
52.4k
    std::unique_ptr<NAL_unit> nal = ctx->nal_parser.pop_from_NAL_queue();
1281
52.4k
    assert(nal);
1282
1283
    // Ownership of the dequeued NAL moves into decode_NAL(), which releases it on
1284
    // every path (directly, or via a slice_unit that returns it to the pool when
1285
    // the image_unit is destroyed). Nothing to free here.
1286
52.4k
    err = ctx->decode_NAL(std::move(nal));
1287
52.4k
    did_work=true;
1288
52.4k
  }
1289
720
  else if (ctx->nal_parser.is_end_of_frame() == true &&
1290
0
      ctx->image_units.empty()) {
1291
0
    if (more) { *more=1; }
1292
1293
0
    return DE265_ERROR_WAITING_FOR_INPUT_DATA;
1294
0
  }
1295
720
  else {
1296
720
    err = decode_some(&did_work);
1297
720
  }
1298
1299
53.3k
  if (more) {
1300
    // decoding error is assumed to be unrecoverable
1301
53.3k
    *more = (err==DE265_OK && did_work);
1302
53.3k
  }
1303
1304
53.1k
  return err;
1305
53.1k
}
1306
1307
1308
void decoder_context::process_nal_hdr(nal_header* nal)
1309
52.5k
{
1310
52.5k
  nal_unit_type = nal->nal_unit_type;
1311
1312
52.5k
  IdrPicFlag = isIdrPic(nal->nal_unit_type);
1313
52.5k
  RapPicFlag = isRapPic(nal->nal_unit_type);
1314
52.5k
}
1315
1316
1317
1318
/* 8.3.1
1319
 */
1320
void decoder_context::process_picture_order_count(slice_segment_header* hdr)
1321
8.52k
{
1322
8.52k
  loginfo(LogHeaders,"POC computation. lsb:%d prev.pic.lsb:%d msb:%d\n",
1323
8.52k
          hdr->slice_pic_order_cnt_lsb,
1324
8.52k
          prevPicOrderCntLsb,
1325
8.52k
          PicOrderCntMsb);
1326
1327
8.52k
  if (isIRAP(nal_unit_type) &&
1328
8.11k
      NoRaslOutputFlag)
1329
8.11k
    {
1330
8.11k
      PicOrderCntMsb=0;
1331
1332
1333
      // flush all images from reorder buffer
1334
1335
8.11k
      flush_reorder_buffer_at_this_frame = true;
1336
      //ctx->dpb.flush_reorder_buffer();
1337
8.11k
    }
1338
414
  else
1339
414
    {
1340
414
      int MaxPicOrderCntLsb = current_sps->MaxPicOrderCntLsb;
1341
1342
414
      if ((hdr->slice_pic_order_cnt_lsb < prevPicOrderCntLsb) &&
1343
56
          (prevPicOrderCntLsb - hdr->slice_pic_order_cnt_lsb) >= MaxPicOrderCntLsb/2) {
1344
8
        PicOrderCntMsb = prevPicOrderCntMsb + MaxPicOrderCntLsb;
1345
8
      }
1346
406
      else if ((hdr->slice_pic_order_cnt_lsb > prevPicOrderCntLsb) &&
1347
316
               (hdr->slice_pic_order_cnt_lsb - prevPicOrderCntLsb) > MaxPicOrderCntLsb/2) {
1348
189
        PicOrderCntMsb = prevPicOrderCntMsb - MaxPicOrderCntLsb;
1349
189
      }
1350
217
      else {
1351
217
        PicOrderCntMsb = prevPicOrderCntMsb;
1352
217
      }
1353
414
    }
1354
1355
8.52k
  img->PicOrderCntVal = PicOrderCntMsb + hdr->slice_pic_order_cnt_lsb;
1356
8.52k
  img->picture_order_cnt_lsb = hdr->slice_pic_order_cnt_lsb;
1357
1358
8.52k
  loginfo(LogHeaders,"POC computation. new msb:%d POC=%d\n",
1359
8.52k
          PicOrderCntMsb,
1360
8.52k
          img->PicOrderCntVal);
1361
1362
8.52k
  if (img->nal_hdr.nuh_temporal_id==0 &&
1363
8.52k
      !isSublayerNonReference(nal_unit_type) &&
1364
8.51k
      !isRASL(nal_unit_type) &&
1365
8.51k
      !isRADL(nal_unit_type))
1366
8.51k
    {
1367
8.51k
      loginfo(LogHeaders,"set prevPicOrderCntLsb/Msb\n");
1368
1369
8.51k
      prevPicOrderCntLsb = hdr->slice_pic_order_cnt_lsb;
1370
8.51k
      prevPicOrderCntMsb = PicOrderCntMsb;
1371
8.51k
    }
1372
8.52k
}
1373
1374
1375
/* 8.3.3.2
1376
   Returns DPB index of the generated picture.
1377
 */
1378
int decoder_context::generate_unavailable_reference_picture(const seq_parameter_set* sps,
1379
                                                            int POC, bool longTerm)
1380
4.37k
{
1381
4.37k
  assert(dpb.has_free_dpb_picture(true));
1382
1383
4.37k
  std::shared_ptr<const seq_parameter_set> current_sps = this->sps[ (int)current_pps->seq_parameter_set_id ];
1384
1385
4.37k
  int idx = dpb.new_image(current_sps, this, 0,0, false);
1386
4.37k
  if (idx<0) {
1387
0
    return idx;
1388
0
  }
1389
1390
4.37k
  de265_image* img = dpb.get_image(idx);
1391
1392
4.37k
  img->fill_image(1<<(sps->BitDepth_Y-1),
1393
4.37k
                  1<<(sps->BitDepth_C-1),
1394
4.37k
                  1<<(sps->BitDepth_C-1));
1395
1396
4.37k
  img->fill_pred_mode(MODE_INTRA);
1397
1398
4.37k
  img->PicOrderCntVal = POC;
1399
4.37k
  img->picture_order_cnt_lsb = POC & (sps->MaxPicOrderCntLsb-1);
1400
4.37k
  img->PicOutputFlag = false;
1401
4.37k
  img->PicState = (longTerm ? UsedForLongTermReference : UsedForShortTermReference);
1402
4.37k
  img->integrity = INTEGRITY_UNAVAILABLE_REFERENCE;
1403
1404
4.37k
  return idx;
1405
4.37k
}
1406
1407
1408
/* 8.3.2   invoked once per picture
1409
1410
   This function will mark pictures in the DPB as 'unused' or 'used for long-term reference'
1411
 */
1412
de265_error decoder_context::process_reference_picture_set(slice_segment_header* hdr)
1413
8.52k
{
1414
8.52k
  std::vector<int> removeReferencesList;
1415
1416
8.52k
  const uint32_t currentID = img->get_ID();
1417
1418
1419
8.52k
  if (isIRAP(nal_unit_type) && NoRaslOutputFlag) {
1420
1421
8.10k
    int currentPOC = img->PicOrderCntVal;
1422
1423
    // reset DPB
1424
1425
    /* The standard says: "When the current picture is an IRAP picture with NoRaslOutputFlag
1426
       equal to 1, all reference pictures currently in the DPB (if any) are marked as
1427
       "unused for reference".
1428
1429
       This seems to be wrong as it also throws out the first CRA picture in a stream like
1430
       RAP_A (decoding order: CRA,POC=64, RASL,POC=60). Removing only the pictures with
1431
       lower POCs seems to be compliant to the reference decoder.
1432
    */
1433
1434
16.2k
    for (size_t i=0;i<dpb.size();i++) {
1435
8.10k
      de265_image* img = dpb.get_image(i);
1436
1437
8.10k
      if (img->PicState != UnusedForReference &&
1438
8.11k
          img->PicOrderCntVal < currentPOC &&
1439
0
          img->removed_at_picture_id > img->get_ID()) {
1440
1441
0
        removeReferencesList.push_back(img->get_ID());
1442
0
        img->removed_at_picture_id = img->get_ID();
1443
1444
        //printf("will remove ID %d (a)\n",img->get_ID());
1445
0
      }
1446
8.10k
    }
1447
8.10k
  }
1448
1449
1450
8.52k
  if (isIDR(nal_unit_type)) {
1451
1452
    // clear all reference pictures
1453
1454
6.24k
    NumPocStCurrBefore = 0;
1455
6.24k
    NumPocStCurrAfter = 0;
1456
6.24k
    NumPocStFoll = 0;
1457
6.24k
    NumPocLtCurr = 0;
1458
6.24k
    NumPocLtFoll = 0;
1459
6.24k
  }
1460
2.28k
  else {
1461
2.28k
    const ref_pic_set* rps = &hdr->CurrRps;
1462
1463
    // (8-98)
1464
1465
2.28k
    int i,j,k;
1466
1467
    // scan ref-pic-set for smaller POCs and fill into PocStCurrBefore / PocStFoll
1468
1469
2.28k
    for (i=0, j=0, k=0;
1470
4.73k
         i<rps->NumNegativePics;
1471
2.45k
         i++)
1472
2.45k
      {
1473
2.45k
        if (rps->UsedByCurrPicS0[i]) {
1474
1.64k
          PocStCurrBefore[j++] = img->PicOrderCntVal + rps->DeltaPocS0[i];
1475
          //printf("PocStCurrBefore = %d\n",PocStCurrBefore[j-1]);
1476
1.64k
        }
1477
814
        else {
1478
814
          PocStFoll[k++] = img->PicOrderCntVal + rps->DeltaPocS0[i];
1479
814
        }
1480
2.45k
      }
1481
1482
2.28k
    NumPocStCurrBefore = j;
1483
1484
1485
    // scan ref-pic-set for larger POCs and fill into PocStCurrAfter / PocStFoll
1486
1487
2.28k
    for (i=0, j=0;
1488
5.88k
         i<rps->NumPositivePics;
1489
3.60k
         i++)
1490
3.60k
      {
1491
3.60k
        if (rps->UsedByCurrPicS1[i]) {
1492
1.78k
          PocStCurrAfter[j++] = img->PicOrderCntVal + rps->DeltaPocS1[i];
1493
          //printf("PocStCurrAfter = %d\n",PocStCurrAfter[j-1]);
1494
1.78k
        }
1495
1.81k
        else {
1496
1.81k
          PocStFoll[k++] = img->PicOrderCntVal + rps->DeltaPocS1[i];
1497
1.81k
        }
1498
3.60k
      }
1499
1500
2.28k
    NumPocStCurrAfter = j;
1501
2.28k
    NumPocStFoll = k;
1502
1503
1504
    // find used / future long-term references
1505
1506
2.28k
    for (i=0, j=0, k=0;
1507
         //i<current_sps->num_long_term_ref_pics_sps + hdr->num_long_term_pics;
1508
3.86k
         i<hdr->num_long_term_sps + hdr->num_long_term_pics;
1509
2.28k
         i++)
1510
1.59k
      {
1511
1.59k
        int pocLt = PocLsbLt[i];
1512
1513
1.59k
        if (hdr->delta_poc_msb_present_flag[i]) {
1514
754
          int currentPictureMSB = img->PicOrderCntVal - hdr->slice_pic_order_cnt_lsb;
1515
754
          if (DeltaPocMsbCycleLt[i] > static_cast<uint32_t>(INT32_MAX) / current_sps->MaxPicOrderCntLsb) {
1516
10
            add_warning(DE265_WARNING_SLICEHEADER_INVALID, false);
1517
10
            return DE265_ERROR_CODED_PARAMETER_OUT_OF_RANGE;
1518
10
          }
1519
744
          pocLt += currentPictureMSB
1520
744
            - static_cast<int>(DeltaPocMsbCycleLt[i] * current_sps->MaxPicOrderCntLsb);
1521
744
        }
1522
1523
1.58k
        if (UsedByCurrPicLt[i]) {
1524
931
          PocLtCurr[j] = pocLt;
1525
931
          CurrDeltaPocMsbPresentFlag[j] = hdr->delta_poc_msb_present_flag[i];
1526
931
          j++;
1527
931
        }
1528
655
        else {
1529
655
          PocLtFoll[k] = pocLt;
1530
655
          FollDeltaPocMsbPresentFlag[k] = hdr->delta_poc_msb_present_flag[i];
1531
655
          k++;
1532
655
        }
1533
1.58k
      }
1534
1535
2.27k
    NumPocLtCurr = j;
1536
2.27k
    NumPocLtFoll = k;
1537
2.27k
  }
1538
1539
1540
  // (old 8-99) / (new 8-106)
1541
  // 1.
1542
1543
8.51k
  std::vector<char> picInAnyList(dpb.size(), false);
1544
1545
1546
8.51k
  dpb.log_dpb_content();
1547
1548
9.43k
  for (int i=0;i<NumPocLtCurr;i++) {
1549
922
    int k;
1550
922
    if (!CurrDeltaPocMsbPresentFlag[i]) {
1551
315
      k = dpb.DPB_index_of_picture_with_LSB(PocLtCurr[i], currentID, true);
1552
315
    }
1553
607
    else {
1554
607
      k = dpb.DPB_index_of_picture_with_POC(PocLtCurr[i], currentID, true);
1555
607
    }
1556
1557
922
    RefPicSetLtCurr[i] = k; // -1 == "no reference picture"
1558
922
    if (k>=0) picInAnyList[k]=true;
1559
716
    else {
1560
      // TODO, CHECK: is it ok that we generate a picture with POC = LSB (PocLtCurr)
1561
      // We do not know the correct MSB
1562
716
      int concealedPicture = generate_unavailable_reference_picture(current_sps.get(),
1563
716
                                                                    PocLtCurr[i], true);
1564
716
      if (concealedPicture<0) {
1565
0
        return (de265_error)(-concealedPicture);
1566
0
      }
1567
716
      picInAnyList.resize(dpb.size(), false); // adjust size of array to hold new picture
1568
1569
716
      RefPicSetLtCurr[i] = k = concealedPicture;
1570
716
      picInAnyList[concealedPicture]=true;
1571
716
    }
1572
1573
922
    if (dpb.get_image(k)->integrity != INTEGRITY_CORRECT) {
1574
876
      img->integrity = INTEGRITY_DERIVED_FROM_FAULTY_REFERENCE;
1575
876
    }
1576
922
  }
1577
1578
1579
9.15k
  for (int i=0;i<NumPocLtFoll;i++) {
1580
641
    int k;
1581
641
    if (!FollDeltaPocMsbPresentFlag[i]) {
1582
519
      k = dpb.DPB_index_of_picture_with_LSB(PocLtFoll[i], currentID, true);
1583
519
    }
1584
122
    else {
1585
122
      k = dpb.DPB_index_of_picture_with_POC(PocLtFoll[i], currentID, true);
1586
122
    }
1587
1588
641
    RefPicSetLtFoll[i] = k; // -1 == "no reference picture"
1589
641
    if (k>=0) picInAnyList[k]=true;
1590
324
    else {
1591
324
      int concealedPicture = k = generate_unavailable_reference_picture(current_sps.get(),
1592
324
                                                                        PocLtFoll[i], true);
1593
324
      if (concealedPicture<0) {
1594
0
        return (de265_error)(-concealedPicture);
1595
0
      }
1596
324
      picInAnyList.resize(dpb.size(), false); // adjust size of array to hold new picture
1597
1598
324
      RefPicSetLtFoll[i] = concealedPicture;
1599
324
      picInAnyList[concealedPicture]=true;
1600
324
    }
1601
641
  }
1602
1603
1604
  // 2. Mark all pictures in RefPicSetLtCurr / RefPicSetLtFoll as UsedForLongTermReference
1605
1606
9.43k
  for (int i=0;i<NumPocLtCurr;i++) {
1607
922
    dpb.get_image(RefPicSetLtCurr[i])->PicState = UsedForLongTermReference;
1608
922
  }
1609
1610
9.15k
  for (int i=0;i<NumPocLtFoll;i++) {
1611
641
    dpb.get_image(RefPicSetLtFoll[i])->PicState = UsedForLongTermReference;
1612
641
  }
1613
1614
1615
  // 3.
1616
1617
10.1k
  for (int i=0;i<NumPocStCurrBefore;i++) {
1618
1.64k
    int k = dpb.DPB_index_of_picture_with_POC(PocStCurrBefore[i], currentID);
1619
1620
    //printf("st curr before, poc=%d -> idx=%d\n",PocStCurrBefore[i], k);
1621
1622
1.64k
    RefPicSetStCurrBefore[i] = k; // -1 == "no reference picture"
1623
1.64k
    if (k>=0) picInAnyList[k]=true;
1624
1.61k
    else {
1625
1.61k
      int concealedPicture = generate_unavailable_reference_picture(current_sps.get(),
1626
1.61k
                                                                    PocStCurrBefore[i], false);
1627
1.61k
      if (concealedPicture<0) {
1628
0
        return (de265_error)(-concealedPicture);
1629
0
      }
1630
1.61k
      RefPicSetStCurrBefore[i] = k = concealedPicture;
1631
1632
1.61k
      picInAnyList.resize(dpb.size(), false); // adjust size of array to hold new picture
1633
1.61k
      picInAnyList[concealedPicture] = true;
1634
1635
      //printf("  concealed: %d\n", concealedPicture);
1636
1.61k
    }
1637
1638
1.64k
    if (dpb.get_image(k)->integrity != INTEGRITY_CORRECT) {
1639
1.64k
      img->integrity = INTEGRITY_DERIVED_FROM_FAULTY_REFERENCE;
1640
1.64k
    }
1641
1.64k
  }
1642
1643
10.2k
  for (int i=0;i<NumPocStCurrAfter;i++) {
1644
1.78k
    int k = dpb.DPB_index_of_picture_with_POC(PocStCurrAfter[i], currentID);
1645
1646
    //printf("st curr after, poc=%d -> idx=%d\n",PocStCurrAfter[i], k);
1647
1648
1.78k
    RefPicSetStCurrAfter[i] = k; // -1 == "no reference picture"
1649
1.78k
    if (k>=0) picInAnyList[k]=true;
1650
1.72k
    else {
1651
1.72k
      int concealedPicture = generate_unavailable_reference_picture(current_sps.get(),
1652
1.72k
                                                                    PocStCurrAfter[i], false);
1653
1.72k
      if (concealedPicture<0) {
1654
0
        return (de265_error)(-concealedPicture);
1655
0
      }
1656
1.72k
      RefPicSetStCurrAfter[i] = k = concealedPicture;
1657
1658
1659
1.72k
      picInAnyList.resize(dpb.size(), false); // adjust size of array to hold new picture
1660
1.72k
      picInAnyList[concealedPicture]=true;
1661
1662
      //printf("  concealed: %d\n", concealedPicture);
1663
1.72k
    }
1664
1665
1.78k
    if (dpb.get_image(k)->integrity != INTEGRITY_CORRECT) {
1666
1.78k
      img->integrity = INTEGRITY_DERIVED_FROM_FAULTY_REFERENCE;
1667
1.78k
    }
1668
1.78k
  }
1669
1670
11.1k
  for (int i=0;i<NumPocStFoll;i++) {
1671
2.63k
    int k = dpb.DPB_index_of_picture_with_POC(PocStFoll[i], currentID);
1672
    // if (k<0) { assert(false); } // IGNORE
1673
1674
2.63k
    RefPicSetStFoll[i] = k; // -1 == "no reference picture"
1675
2.63k
    if (k>=0) picInAnyList[k]=true;
1676
2.63k
  }
1677
1678
  // 4. any picture that is not marked for reference is put into the "UnusedForReference" state
1679
1680
22.4k
  for (size_t i=0;i<dpb.size();i++)
1681
13.9k
    if (i>=picInAnyList.size() || !picInAnyList[i])        // no reference
1682
9.32k
      {
1683
9.32k
        de265_image* dpbimg = dpb.get_image(i);
1684
9.32k
        if (dpbimg != img &&  // not the current picture
1685
898
            dpbimg->removed_at_picture_id > img->get_ID()) // has not been removed before
1686
761
          {
1687
761
            if (dpbimg->PicState != UnusedForReference) {
1688
761
              removeReferencesList.push_back(dpbimg->get_ID());
1689
              //printf("will remove ID %d (b)\n",dpbimg->get_ID());
1690
1691
761
              dpbimg->removed_at_picture_id = img->get_ID();
1692
761
            }
1693
761
          }
1694
9.32k
      }
1695
1696
8.51k
  hdr->RemoveReferencesList = removeReferencesList;
1697
1698
  //remove_images_from_dpb(hdr->RemoveReferencesList);
1699
1700
8.51k
  return DE265_OK;
1701
8.51k
}
1702
1703
1704
// 8.3.4
1705
// Returns whether we can continue decoding (or whether there is a severe error).
1706
/* Called at beginning of each slice.
1707
1708
   Constructs
1709
   - the RefPicList[2][], containing indices into the DPB, and
1710
   - the RefPicList_POC[2][], containing POCs.
1711
   - LongTermRefPic[2][] is also set to true if it is a long-term reference
1712
 */
1713
bool decoder_context::construct_reference_picture_lists(slice_segment_header* hdr)
1714
1.59k
{
1715
1.59k
  int NumPocTotalCurr = hdr->NumPocTotalCurr;
1716
1.59k
  int NumRpsCurrTempList0 = std::max((int)hdr->num_ref_idx_l0_active, NumPocTotalCurr);
1717
1718
  // TODO: fold code for both lists together
1719
1720
1.59k
  int RefPicListTemp0[3*MAX_NUM_REF_PICS]; // TODO: what would be the correct maximum ?
1721
1.59k
  int RefPicListTemp1[3*MAX_NUM_REF_PICS]; // TODO: what would be the correct maximum ?
1722
1.59k
  char isLongTerm[2][3*MAX_NUM_REF_PICS];
1723
1724
1.59k
  memset(isLongTerm,0,2*3*MAX_NUM_REF_PICS);
1725
1726
  /* --- Fill RefPicListTmp0 with reference pictures in this order:
1727
     1) short term, past POC
1728
     2) short term, future POC
1729
     3) long term
1730
  */
1731
1732
1.59k
  int rIdx=0;
1733
4.32k
  while (rIdx < NumRpsCurrTempList0) {
1734
4.08k
    for (int i=0;i<NumPocStCurrBefore && rIdx<NumRpsCurrTempList0; rIdx++,i++)
1735
1.25k
      RefPicListTemp0[rIdx] = RefPicSetStCurrBefore[i];
1736
1737
5.12k
    for (int i=0;i<NumPocStCurrAfter && rIdx<NumRpsCurrTempList0; rIdx++,i++)
1738
2.30k
      RefPicListTemp0[rIdx] = RefPicSetStCurrAfter[i];
1739
1740
4.51k
    for (int i=0;i<NumPocLtCurr && rIdx<NumRpsCurrTempList0; rIdx++,i++) {
1741
1.68k
      RefPicListTemp0[rIdx] = RefPicSetLtCurr[i];
1742
1.68k
      isLongTerm[0][rIdx] = true;
1743
1.68k
    }
1744
1745
    // This check is to prevent an endless loop when no images are added above.
1746
2.82k
    if (rIdx==0) {
1747
95
      add_warning(DE265_WARNING_FAULTY_REFERENCE_PICTURE_LIST, false);
1748
95
      return false;
1749
95
    }
1750
2.82k
  }
1751
1752
  /*
1753
  if (hdr->num_ref_idx_l0_active > 16) {
1754
    add_warning(DE265_WARNING_NONEXISTING_REFERENCE_PICTURE_ACCESSED, false);
1755
    return false;
1756
  }
1757
  */
1758
1759
1.59k
  assert(hdr->num_ref_idx_l0_active <= 16);
1760
5.48k
  for (rIdx=0; rIdx<hdr->num_ref_idx_l0_active; rIdx++) {
1761
4.03k
    int idx = hdr->ref_pic_list_modification_flag_l0 ? hdr->list_entry_l0[rIdx] : rIdx;
1762
1763
4.03k
    if (idx >= NumRpsCurrTempList0) {
1764
52
      add_warning(DE265_WARNING_FAULTY_REFERENCE_PICTURE_LIST, false);
1765
52
      return false;
1766
52
    }
1767
1768
3.97k
    hdr->RefPicList[0][rIdx] = RefPicListTemp0[idx];
1769
3.97k
    hdr->LongTermRefPic[0][rIdx] = isLongTerm[0][idx];
1770
1771
    // remember POC of referenced image (needed in motion.c, derive_collocated_motion_vector)
1772
3.97k
    de265_image* img_0_rIdx = dpb.get_image(hdr->RefPicList[0][rIdx]);
1773
3.97k
    if (img_0_rIdx==nullptr) {
1774
0
      return false;
1775
0
    }
1776
3.97k
    hdr->RefPicList_POC[0][rIdx] = img_0_rIdx->PicOrderCntVal;
1777
3.97k
    hdr->RefPicList_PicState[0][rIdx] = img_0_rIdx->PicState;
1778
3.97k
  }
1779
1780
1781
  /* --- Fill RefPicListTmp1 with reference pictures in this order:
1782
     1) short term, future POC
1783
     2) short term, past POC
1784
     3) long term
1785
  */
1786
1787
1.45k
  if (hdr->slice_type == SLICE_TYPE_B) {
1788
1.30k
    int NumRpsCurrTempList1 = std::max((int)hdr->num_ref_idx_l1_active, NumPocTotalCurr);
1789
1790
1.30k
    int rIdx=0;
1791
3.37k
    while (rIdx < NumRpsCurrTempList1) {
1792
3.84k
      for (int i=0;i<NumPocStCurrAfter && rIdx<NumRpsCurrTempList1; rIdx++,i++) {
1793
1.77k
        RefPicListTemp1[rIdx] = RefPicSetStCurrAfter[i];
1794
1.77k
      }
1795
1796
3.11k
      for (int i=0;i<NumPocStCurrBefore && rIdx<NumRpsCurrTempList1; rIdx++,i++) {
1797
1.04k
        RefPicListTemp1[rIdx] = RefPicSetStCurrBefore[i];
1798
1.04k
      }
1799
1800
3.41k
      for (int i=0;i<NumPocLtCurr && rIdx<NumRpsCurrTempList1; rIdx++,i++) {
1801
1.34k
        RefPicListTemp1[rIdx] = RefPicSetLtCurr[i];
1802
1.34k
        isLongTerm[1][rIdx] = true;
1803
1.34k
      }
1804
1805
      // This check is to prevent an endless loop when no images are added above.
1806
2.07k
      if (rIdx==0) {
1807
0
        add_warning(DE265_WARNING_FAULTY_REFERENCE_PICTURE_LIST, false);
1808
0
        return false;
1809
0
      }
1810
2.07k
    }
1811
1812
1.30k
    if (hdr->num_ref_idx_l0_active > 16) {
1813
0
    add_warning(DE265_WARNING_NONEXISTING_REFERENCE_PICTURE_ACCESSED, false);
1814
0
    return false;
1815
0
  }
1816
1817
1.30k
    assert(hdr->num_ref_idx_l1_active <= 16);
1818
4.23k
    for (rIdx=0; rIdx<hdr->num_ref_idx_l1_active; rIdx++) {
1819
2.93k
      int idx = hdr->ref_pic_list_modification_flag_l1 ? hdr->list_entry_l1[rIdx] : rIdx;
1820
1821
2.93k
      if (idx >= NumRpsCurrTempList1) {
1822
2
        add_warning(DE265_WARNING_FAULTY_REFERENCE_PICTURE_LIST, false);
1823
2
        return false;
1824
2
      }
1825
1826
2.93k
      hdr->RefPicList[1][rIdx] = RefPicListTemp1[idx];
1827
2.93k
      hdr->LongTermRefPic[1][rIdx] = isLongTerm[1][idx];
1828
1829
      // remember POC of referenced imaged (needed in motion.c, derive_collocated_motion_vector)
1830
2.93k
      de265_image* img_1_rIdx = dpb.get_image(hdr->RefPicList[1][rIdx]);
1831
2.93k
      if (img_1_rIdx == nullptr) { return false; }
1832
2.93k
      hdr->RefPicList_POC[1][rIdx] = img_1_rIdx->PicOrderCntVal;
1833
2.93k
      hdr->RefPicList_PicState[1][rIdx] = img_1_rIdx->PicState;
1834
2.93k
    }
1835
1.30k
  }
1836
1837
1838
  // show reference picture lists
1839
1840
1.44k
  loginfo(LogHeaders,"RefPicList[0] =");
1841
5.42k
  for (rIdx=0; rIdx<hdr->num_ref_idx_l0_active; rIdx++) {
1842
3.97k
    loginfo(LogHeaders,"* [%d]=%d (LT=%d)",
1843
3.97k
            hdr->RefPicList[0][rIdx],
1844
3.97k
            hdr->RefPicList_POC[0][rIdx],
1845
3.97k
            hdr->LongTermRefPic[0][rIdx]
1846
3.97k
            );
1847
3.97k
  }
1848
1.44k
  loginfo(LogHeaders,"*\n");
1849
1850
1.44k
  if (hdr->slice_type == SLICE_TYPE_B) {
1851
1.29k
    loginfo(LogHeaders,"RefPicList[1] =");
1852
4.23k
    for (rIdx=0; rIdx<hdr->num_ref_idx_l1_active; rIdx++) {
1853
2.93k
      loginfo(LogHeaders,"* [%d]=%d (LT=%d)",
1854
2.93k
              hdr->RefPicList[1][rIdx],
1855
2.93k
              hdr->RefPicList_POC[1][rIdx],
1856
2.93k
              hdr->LongTermRefPic[1][rIdx]
1857
2.93k
              );
1858
2.93k
    }
1859
1.29k
    loginfo(LogHeaders,"*\n");
1860
1.29k
  }
1861
1862
1.44k
  return true;
1863
1.45k
}
1864
1865
1866
1867
void decoder_context::run_postprocessing_filters_sequential(de265_image* img)
1868
0
{
1869
#if SAVE_INTERMEDIATE_IMAGES
1870
    char buf[1000];
1871
    sprintf(buf,"pre-lf-%05d.yuv", img->PicOrderCntVal);
1872
    write_picture_to_file(img, buf);
1873
#endif
1874
1875
0
    if (!img->decctx->param_disable_deblocking) {
1876
0
      apply_deblocking_filter(img);
1877
0
    }
1878
1879
#if SAVE_INTERMEDIATE_IMAGES
1880
    sprintf(buf,"pre-sao-%05d.yuv", img->PicOrderCntVal);
1881
    write_picture_to_file(img, buf);
1882
#endif
1883
1884
0
    if (!img->decctx->param_disable_sao) {
1885
0
      apply_sample_adaptive_offset_sequential(img);
1886
0
    }
1887
1888
#if SAVE_INTERMEDIATE_IMAGES
1889
    sprintf(buf,"sao-%05d.yuv", img->PicOrderCntVal);
1890
    write_picture_to_file(img, buf);
1891
#endif
1892
0
}
1893
1894
1895
void decoder_context::run_postprocessing_filters_parallel(image_unit* imgunit)
1896
8.26k
{
1897
8.26k
  de265_image* img = imgunit->img;
1898
1899
8.26k
  int saoWaitsForProgress = CTB_PROGRESS_PREFILTER;
1900
8.26k
  bool waitForCompletion = false;
1901
1902
8.26k
  if (!img->decctx->param_disable_deblocking) {
1903
8.26k
    add_deblocking_tasks(imgunit);
1904
8.26k
    saoWaitsForProgress = CTB_PROGRESS_DEBLK_H;
1905
8.26k
  }
1906
1907
8.26k
  if (!img->decctx->param_disable_sao) {
1908
8.26k
    waitForCompletion |= add_sao_tasks(imgunit, saoWaitsForProgress);
1909
    //apply_sample_adaptive_offset(img);
1910
8.26k
  }
1911
1912
  // The original intention was to skip wait_for_completion() if there is no SAO task,
1913
  // but it does not work as intended. (TODO: check why)
1914
8.26k
  (void)waitForCompletion;
1915
1916
8.26k
  img->wait_for_completion();
1917
8.26k
}
1918
1919
/*
1920
void decoder_context::push_current_picture_to_output_queue()
1921
{
1922
  push_picture_to_output_queue(img);
1923
}
1924
*/
1925
1926
de265_error decoder_context::push_picture_to_output_queue(image_unit* imgunit)
1927
8.26k
{
1928
8.26k
  de265_image* outimg = imgunit->img;
1929
1930
8.26k
  if (outimg==nullptr) { return DE265_OK; }
1931
1932
1933
  // push image into output queue
1934
1935
8.26k
  if (outimg->PicOutputFlag) {
1936
8.20k
    loginfo(LogDPB,"new picture has output-flag=true\n");
1937
1938
8.20k
    if (outimg->integrity != INTEGRITY_CORRECT &&
1939
4.81k
        param_suppress_faulty_pictures) {
1940
0
    }
1941
8.20k
    else {
1942
8.20k
      dpb.insert_image_into_reorder_buffer(outimg);
1943
8.20k
    }
1944
1945
8.20k
    loginfo(LogDPB,"push image %d into reordering queue\n", outimg->PicOrderCntVal);
1946
8.20k
  }
1947
1948
  // check for full reorder buffers
1949
1950
8.26k
  int maxNumPicsInReorderBuffer = 0;
1951
1952
  // TODO: I'd like to have the has_vps() check somewhere else (not decode the picture at all)
1953
8.26k
  if (outimg->has_vps()) {
1954
6.15k
    int sublayer = outimg->get_vps().vps_max_sub_layers -1;
1955
6.15k
    maxNumPicsInReorderBuffer = outimg->get_vps().layer[sublayer].vps_max_num_reorder_pics;
1956
6.15k
  }
1957
1958
8.26k
  if (dpb.num_pictures_in_reorder_buffer() > maxNumPicsInReorderBuffer) {
1959
8.19k
    dpb.output_next_picture_in_reorder_buffer();
1960
8.19k
  }
1961
1962
8.26k
  dpb.log_dpb_queues();
1963
1964
8.26k
  return DE265_OK;
1965
8.26k
}
1966
1967
1968
// returns whether we can continue decoding the stream or whether we should give up
1969
bool decoder_context::process_slice_segment_header(slice_segment_header* hdr,
1970
                                                   de265_error* err, de265_PTS pts,
1971
                                                   nal_header* nal_hdr,
1972
                                                   void* user_data)
1973
8.54k
{
1974
8.54k
  *err = DE265_OK;
1975
1976
8.54k
  flush_reorder_buffer_at_this_frame = false;
1977
1978
1979
  // get PPS and SPS for this slice
1980
1981
8.54k
  int pps_id = hdr->slice_pic_parameter_set_id;
1982
8.55k
  if (pps[pps_id]==nullptr || pps[pps_id]->pps_read==false) {
1983
0
    logerror(LogHeaders, "PPS %d has not been read\n", pps_id);
1984
0
    img->decctx->add_warning(DE265_WARNING_NONEXISTING_PPS_REFERENCED, false);
1985
0
    return false;
1986
0
  }
1987
1988
8.54k
  current_pps = pps[pps_id];
1989
8.54k
  current_sps = sps[ (int)current_pps->seq_parameter_set_id ];
1990
8.54k
  current_vps = vps[ (int)current_sps->video_parameter_set_id ];
1991
1992
8.54k
  calc_tid_and_framerate_ratio();
1993
1994
1995
  // --- prepare decoding of new picture ---
1996
1997
8.54k
  if (hdr->first_slice_segment_in_pic_flag) {
1998
1999
    // previous picture has been completely decoded
2000
2001
    //ctx->push_current_picture_to_output_queue();
2002
2003
8.53k
    current_image_poc_lsb = hdr->slice_pic_order_cnt_lsb;
2004
2005
2006
8.53k
    seq_parameter_set* sps = current_sps.get();
2007
2008
2009
    // --- find and allocate image buffer for decoding ---
2010
2011
8.53k
    int image_buffer_idx;
2012
8.53k
    bool isOutputImage = (!sps->sample_adaptive_offset_enabled_flag || param_disable_sao);
2013
8.53k
    image_buffer_idx = dpb.new_image(current_sps, this, pts, user_data, isOutputImage);
2014
8.53k
    if (image_buffer_idx < 0) {
2015
0
      *err = (de265_error)(-image_buffer_idx);
2016
0
      return false;
2017
0
    }
2018
2019
8.53k
    /*de265_image* */ img = dpb.get_image(image_buffer_idx);
2020
8.53k
    img->nal_hdr = *nal_hdr;
2021
2022
    // Note: sps is already set in new_image() -> ??? still the case with shared_ptr ?
2023
2024
8.53k
    img->set_headers(current_vps, current_sps, current_pps);
2025
2026
8.53k
    img->decctx = this;
2027
2028
8.53k
    img->clear_metadata();
2029
2030
2031
8.53k
    if (isIRAP(nal_unit_type)) {
2032
8.11k
      if (isIDR(nal_unit_type) ||
2033
1.87k
          isBLA(nal_unit_type) ||
2034
653
          first_decoded_picture ||
2035
0
          FirstAfterEndOfSequenceNAL)
2036
8.11k
        {
2037
8.11k
          NoRaslOutputFlag = true;
2038
8.11k
          FirstAfterEndOfSequenceNAL = false;
2039
8.11k
        }
2040
18.4E
      else if (0) // TODO: set HandleCraAsBlaFlag by external means
2041
0
        {
2042
0
        }
2043
18.4E
      else
2044
18.4E
        {
2045
18.4E
          NoRaslOutputFlag   = false;
2046
18.4E
          HandleCraAsBlaFlag = false;
2047
18.4E
        }
2048
8.11k
    }
2049
2050
2051
8.53k
    if (isRASL(nal_unit_type) &&
2052
5
        NoRaslOutputFlag)
2053
2
      {
2054
2
        img->PicOutputFlag = false;
2055
2
      }
2056
8.53k
    else
2057
8.53k
      {
2058
8.53k
        img->PicOutputFlag = !!hdr->pic_output_flag;
2059
8.53k
      }
2060
2061
8.53k
    process_picture_order_count(hdr);
2062
2063
8.53k
    if (hdr->first_slice_segment_in_pic_flag) {
2064
      // mark picture so that it is not overwritten by unavailable reference frames
2065
8.52k
      img->PicState = UsedForShortTermReference;
2066
2067
8.52k
      *err = process_reference_picture_set(hdr);
2068
8.52k
      if (*err != DE265_OK) {
2069
10
        return false;
2070
10
      }
2071
8.52k
    }
2072
2073
8.52k
    img->PicState = UsedForShortTermReference;
2074
2075
8.52k
    log_set_current_POC(img->PicOrderCntVal);
2076
2077
2078
    // next image is not the first anymore
2079
2080
8.52k
    first_decoded_picture = false;
2081
8.52k
  }
2082
14
  else {
2083
    // claims to be not the first slice, but there is no active image available
2084
2085
14
    if (img == nullptr) {
2086
6
      return false;
2087
6
    }
2088
14
  }
2089
2090
8.53k
  if (hdr->slice_type == SLICE_TYPE_B ||
2091
7.22k
      hdr->slice_type == SLICE_TYPE_P)
2092
1.59k
    {
2093
1.59k
      bool success = construct_reference_picture_lists(hdr);
2094
1.59k
      if (!success) {
2095
149
        return false;
2096
149
      }
2097
1.59k
    }
2098
2099
  //printf("process slice segment header\n");
2100
2101
8.38k
  loginfo(LogHeaders,"end of process-slice-header\n");
2102
8.38k
  dpb.log_dpb_content();
2103
2104
2105
8.40k
  if (hdr->dependent_slice_segment_flag==0) {
2106
8.40k
    hdr->SliceAddrRS = hdr->slice_segment_address;
2107
18.4E
  } else {
2108
18.4E
    hdr->SliceAddrRS = previous_slice_header->SliceAddrRS;
2109
18.4E
  }
2110
2111
  // Note: previous_slice_header is updated by the caller (read_slice_NAL) only
2112
  // once the slice header is actually retained by the image. Setting it here
2113
  // would leave a dangling pointer when the caller discards/deletes 'hdr'.
2114
2115
2116
8.38k
  loginfo(LogHeaders,"SliceAddrRS = %d\n",hdr->SliceAddrRS);
2117
2118
8.38k
  return true;
2119
8.53k
}
2120
2121
2122
void decoder_context::remove_images_from_dpb(const std::vector<int>& removeImageList)
2123
15.4k
{
2124
15.7k
  for (size_t i=0;i<removeImageList.size();i++) {
2125
243
    int idx = dpb.DPB_index_of_picture_with_ID( removeImageList[i] );
2126
243
    if (idx>=0) {
2127
      //printf("remove ID %d\n", removeImageList[i]);
2128
243
      de265_image* dpbimg = dpb.get_image( idx );
2129
243
      dpbimg->PicState = UnusedForReference;
2130
243
    }
2131
243
  }
2132
15.4k
}
2133
2134
2135
2136
/*
2137
  .     0     1     2       <- goal_HighestTid
2138
  +-----+-----+-----+
2139
  | -0->| -1->| -2->|
2140
  +-----+-----+-----+
2141
  0     33    66    100     <- framerate_ratio
2142
 */
2143
2144
int  decoder_context::get_highest_TID() const
2145
25.9k
{
2146
25.9k
  if (current_sps) { return current_sps->sps_max_sub_layers-1; }
2147
9.07k
  if (current_vps) { return current_vps->vps_max_sub_layers-1; }
2148
2149
9.07k
  return 6;
2150
9.07k
}
2151
2152
void decoder_context::set_limit_TID(int max_tid)
2153
0
{
2154
0
  limit_HighestTid = max_tid;
2155
0
  calc_tid_and_framerate_ratio();
2156
0
}
2157
2158
int decoder_context::change_framerate(int more)
2159
0
{
2160
0
  if (current_sps == nullptr) { return framerate_ratio; }
2161
2162
0
  int highestTid = get_highest_TID();
2163
2164
0
  assert(more>=-1 && more<=1);
2165
2166
0
  goal_HighestTid += more;
2167
0
  goal_HighestTid = std::max(goal_HighestTid, 0);
2168
0
  goal_HighestTid = std::min(goal_HighestTid, highestTid);
2169
2170
0
  framerate_ratio = framedrop_tid_index[goal_HighestTid];
2171
2172
0
  calc_tid_and_framerate_ratio();
2173
2174
0
  return framerate_ratio;
2175
0
}
2176
2177
void decoder_context::set_framerate_ratio(int percent)
2178
0
{
2179
0
  framerate_ratio = percent;
2180
0
  calc_tid_and_framerate_ratio();
2181
0
}
2182
2183
void decoder_context::compute_framedrop_table()
2184
17.3k
{
2185
17.3k
  int highestTID = get_highest_TID();
2186
2187
89.4k
  for (int tid=highestTID ; tid>=0 ; tid--) {
2188
72.1k
    int lower  = 100 *  tid   /(highestTID+1);
2189
72.1k
    int higher = 100 * (tid+1)/(highestTID+1);
2190
2191
1.87M
    for (int l=lower; l<=higher; l++) {
2192
1.80M
      int ratio = 100 * (l-lower) / (higher-lower);
2193
2194
      // if we would exceed our TID limit, decode the highest TID at full frame-rate
2195
1.80M
      if (tid > limit_HighestTid) {
2196
0
        tid   = limit_HighestTid;
2197
0
        ratio = 100;
2198
0
      }
2199
2200
1.80M
      framedrop_tab[l].tid   = tid;
2201
1.80M
      framedrop_tab[l].ratio = ratio;
2202
1.80M
    }
2203
2204
72.1k
    framedrop_tid_index[tid] = higher;
2205
72.1k
  }
2206
2207
#if 0
2208
  for (int i=0;i<=100;i++) {
2209
    printf("%d%%: %d/%d",i, framedrop_tab[i].tid, framedrop_tab[i].ratio);
2210
    for (int k=0;k<=highestTID;k++) {
2211
      if (framedrop_tid_index[k] == i) printf(" ** TID=%d **",k);
2212
    }
2213
    printf("\n");
2214
  }
2215
#endif
2216
17.3k
}
2217
2218
void decoder_context::calc_tid_and_framerate_ratio()
2219
8.57k
{
2220
8.57k
  int highestTID = get_highest_TID();
2221
2222
2223
  // if number of temporal layers changed, we have to recompute the framedrop table
2224
2225
8.57k
  if (framedrop_tab[100].tid != highestTID) {
2226
8.28k
    compute_framedrop_table();
2227
8.28k
  }
2228
2229
8.57k
  goal_HighestTid       = framedrop_tab[framerate_ratio].tid;
2230
8.57k
  layer_framerate_ratio = framedrop_tab[framerate_ratio].ratio;
2231
2232
  // TODO: for now, we switch immediately
2233
8.57k
  current_HighestTid = goal_HighestTid;
2234
8.57k
}
2235
2236
2237
void error_queue::add_warning(de265_error warning, bool once)
2238
35.8k
{
2239
35.8k
  std::lock_guard<std::mutex> lock(m_mutex);
2240
2241
  // check if warning was already shown
2242
35.8k
  if (once) {
2243
22.8k
    if (std::find(warnings_shown.begin(), warnings_shown.end(), warning) != warnings_shown.end()) {
2244
15.5k
      return;
2245
15.5k
    }
2246
7.23k
    warnings_shown.push_back(warning);
2247
7.23k
  }
2248
2249
  // add warning to output queue
2250
20.3k
  if (warnings.size() >= MAX_WARNINGS) {
2251
1.00k
    warnings.back() = DE265_WARNING_WARNING_BUFFER_FULL;
2252
1.00k
    return;
2253
1.00k
  }
2254
2255
19.3k
  warnings.push_back(warning);
2256
19.3k
}
2257
2258
de265_error error_queue::get_warning()
2259
0
{
2260
0
  std::lock_guard<std::mutex> lock(m_mutex);
2261
2262
0
  if (warnings.empty()) {
2263
0
    return DE265_OK;
2264
0
  }
2265
2266
0
  de265_error warn = warnings.front();
2267
0
  warnings.erase(warnings.begin());
2268
2269
0
  return warn;
2270
0
}