Coverage Report

Created: 2026-08-13 07:20

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