Coverage Report

Created: 2026-07-30 06:26

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
0
{
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
0
  int offset = ((uintptr_t)_coeffBuf) & 0xf;
66
67
0
  if (offset == 0) {
68
0
    coeffBuf = _coeffBuf;
69
0
  }
70
0
  else {
71
0
    coeffBuf = (int16_t *) (((uint8_t *)_coeffBuf) + (16-offset));
72
0
  }
73
74
0
  memset(coeffBuf, 0, 32*32*sizeof(int16_t));
75
0
}
76
77
78
slice_unit::slice_unit(decoder_context* decctx)
79
0
  : nal(nullptr),
80
0
    shdr(nullptr),
81
0
    imgunit(nullptr),
82
0
    flush_reorder_buffer(false),
83
0
    nThreads(0),
84
0
    first_decoded_CTB_RS(-1),
85
0
    last_decoded_CTB_RS(-1),
86
0
    thread_contexts(nullptr),
87
0
    ctx(decctx)
88
0
{
89
0
  state = Unprocessed;
90
0
  nThreadContexts = 0;
91
0
}
92
93
slice_unit::~slice_unit()
94
0
{
95
0
  ctx->nal_parser.free_NAL_unit(nal);
96
97
0
  if (thread_contexts) {
98
0
    delete[] thread_contexts;
99
0
  }
100
0
}
101
102
103
void slice_unit::allocate_thread_contexts(int n)
104
0
{
105
0
  assert(thread_contexts==nullptr);
106
107
0
  thread_contexts = new thread_context[n];
108
0
  nThreadContexts = n;
109
0
}
110
111
112
0
image_unit::image_unit() = default;
113
114
115
image_unit::~image_unit()
116
0
{
117
0
  for (size_t i=0;i<slice_units.size();i++) {
118
0
    delete slice_units[i];
119
0
  }
120
121
0
  for (size_t i=0;i<tasks.size();i++) {
122
0
    delete tasks[i];
123
0
  }
124
0
}
125
126
127
base_context::base_context()
128
0
{
129
0
  set_acceleration_functions(de265_acceleration_AUTO);
130
0
}
131
132
133
decoder_context::decoder_context()
134
0
{
135
0
  param_image_allocation_functions = de265_image::default_image_allocation;
136
0
  nal_parser.set_security_limits(&param_security_limits);
137
0
  compute_framedrop_table();
138
0
}
139
140
141
decoder_context::~decoder_context()
142
0
{
143
0
  while (!image_units.empty()) {
144
0
    delete image_units.back();
145
0
    image_units.pop_back();
146
0
  }
147
0
}
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
0
{
168
0
  thread_pool_.start(nThreads);
169
170
0
  num_worker_threads = nThreads;
171
172
0
  return DE265_OK;
173
0
}
174
175
176
void decoder_context::stop_thread_pool()
177
0
{
178
0
  if (get_num_worker_threads()>0) {
179
    //flush_thread_pool(&ctx->thread_pool);
180
0
    thread_pool_.stop();
181
0
  }
182
0
}
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
0
{
241
  // fill scalar functions first (so that function table is completely filled)
242
243
0
  init_acceleration_functions_fallback(&acceleration);
244
245
246
  // override functions with optimized variants
247
248
0
#ifdef HAVE_SSE4_1
249
0
  if (l>=de265_acceleration_SSE) {
250
0
    init_acceleration_functions_sse(&acceleration);
251
0
  }
252
0
#endif
253
0
#if HAVE_AVX2
254
  // layered on top of SSE: overrides a few transform kernels (runtime-checked)
255
0
  if (l>=de265_acceleration_AVX2) {
256
0
    init_acceleration_functions_avx2(&acceleration);
257
0
  }
258
0
#endif
259
0
#if HAVE_AVX512
260
  // layered on top of AVX2: overrides the 32x32 transform (runtime-checked)
261
0
  if (l>=de265_acceleration_AVX2) {
262
0
    init_acceleration_functions_avx512(&acceleration);
263
0
  }
264
0
#endif
265
#ifdef HAVE_ARM32
266
  if (l>=de265_acceleration_ARM) {
267
    init_acceleration_functions_arm(&acceleration);
268
  }
269
#endif
270
0
}
271
272
273
void decoder_context::init_thread_context(thread_context* tctx)
274
0
{
275
  // zero scrap memory for coefficient blocks
276
0
  memset(tctx->_coeffBuf, 0, sizeof(tctx->_coeffBuf));  // TODO: check if we can safely remove this
277
278
0
  tctx->currentQG_x = -1;
279
0
  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
0
  const pic_parameter_set& pps = tctx->img->get_pps();
288
0
  const seq_parameter_set& sps = tctx->img->get_sps();
289
290
291
0
  if (tctx->shdr->slice_segment_address > 0) {
292
0
    int prevCtb = pps.scan->CtbAddrTStoRS[ pps.scan->CtbAddrRStoTS[tctx->shdr->slice_segment_address] -1 ];
293
294
0
    int ctbX = prevCtb % sps.PicWidthInCtbsY;
295
0
    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
0
    int x = ((ctbX+1) << sps.Log2CtbSizeY)-1;
301
0
    int y = ((ctbY+1) << sps.Log2CtbSizeY)-1;
302
303
0
    x = std::min(x,sps.pic_width_in_luma_samples-1);
304
0
    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
0
    tctx->currentQPY = tctx->img->get_QPY(x,y);
310
      //}
311
0
  }
312
0
}
313
314
315
void decoder_context::add_task_decode_CTB_row(thread_context* tctx,
316
                                              bool firstSliceSubstream,
317
                                              uint16_t ctbRow)
318
0
{
319
0
  thread_task_ctb_row* task = new thread_task_ctb_row;
320
0
  task->firstSliceSubstream = firstSliceSubstream;
321
0
  task->tctx = tctx;
322
0
  task->debug_startCtbRow = ctbRow;
323
0
  tctx->task = task;
324
325
0
  thread_pool_.add_task(task);
326
327
0
  tctx->imgunit->tasks.push_back(task);
328
0
}
329
330
331
void decoder_context::add_task_decode_slice_segment(thread_context* tctx, bool firstSliceSubstream,
332
                                                    uint16_t ctbx, uint16_t ctby)
333
0
{
334
0
  thread_task_slice_segment* task = new thread_task_slice_segment;
335
0
  task->firstSliceSubstream = firstSliceSubstream;
336
0
  task->tctx = tctx;
337
0
  task->debug_startCtbX = ctbx;
338
0
  task->debug_startCtbY = ctby;
339
0
  tctx->task = task;
340
341
0
  thread_pool_.add_task(task);
342
343
0
  tctx->imgunit->tasks.push_back(task);
344
0
}
345
346
347
de265_error decoder_context::read_vps_NAL(bitreader& reader)
348
0
{
349
0
  logdebug(LogHeaders,"---> read VPS\n");
350
351
0
  std::shared_ptr<video_parameter_set> new_vps = std::make_shared<video_parameter_set>();
352
0
  de265_error err = new_vps->read(this,&reader);
353
0
  if (err != DE265_OK) {
354
0
    return err;
355
0
  }
356
357
0
  if (param_vps_headers_fd>=0) {
358
0
    new_vps->dump(param_vps_headers_fd);
359
0
  }
360
361
0
  vps[ new_vps->video_parameter_set_id ] = new_vps;
362
363
0
  return DE265_OK;
364
0
}
365
366
de265_error decoder_context::read_sps_NAL(bitreader& reader)
367
0
{
368
0
  logdebug(LogHeaders,"----> read SPS\n");
369
370
0
  std::shared_ptr<seq_parameter_set> new_sps = std::make_shared<seq_parameter_set>();
371
0
  de265_error err;
372
373
0
  if ((err=new_sps->read(this, &reader)) != DE265_OK) {
374
0
    return err;
375
0
  }
376
377
0
  if (param_sps_headers_fd>=0) {
378
0
    new_sps->dump(param_sps_headers_fd);
379
0
  }
380
381
0
  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
0
  for (auto& p : pps) {
387
0
    if (p && p->seq_parameter_set_id == new_sps->seq_parameter_set_id) {
388
0
      p = nullptr;
389
0
    }
390
0
  }
391
392
0
  return DE265_OK;
393
0
}
394
395
de265_error decoder_context::read_pps_NAL(bitreader& reader)
396
0
{
397
0
  logdebug(LogHeaders,"----> read PPS\n");
398
399
0
  std::shared_ptr<pic_parameter_set> new_pps = std::make_shared<pic_parameter_set>();
400
401
0
  bool success = new_pps->read(&reader,this);
402
0
  if (!success) {
403
0
    return DE265_WARNING_PPS_HEADER_INVALID;
404
0
  }
405
406
0
  if (param_pps_headers_fd>=0) {
407
0
    new_pps->dump(param_pps_headers_fd);
408
0
  }
409
410
0
  pps[ (int)new_pps->pic_parameter_set_id ] = new_pps;
411
412
0
  return DE265_OK;
413
0
}
414
415
de265_error decoder_context::read_sei_NAL(bitreader& reader, bool suffix)
416
0
{
417
0
  logdebug(LogHeaders,"----> read SEI\n");
418
419
0
  sei_message sei;
420
421
  //push_current_picture_to_output_queue();
422
423
0
  de265_error err = DE265_OK;
424
425
0
  if ((err=read_sei(&reader,&sei, suffix, current_sps.get())) == DE265_OK) {
426
0
    dump_sei(&sei, current_sps.get());
427
428
0
    if (image_units.empty()==false && suffix) {
429
0
      uint32_t max_SEI_messages = param_security_limits.max_SEI_messages;
430
0
      if (max_SEI_messages != 0 &&
431
0
          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
0
      image_units.back()->suffix_SEIs.push_back(sei);
438
0
    }
439
0
  }
440
0
  else {
441
0
    add_warning(err, false);
442
0
  }
443
444
0
  return err;
445
0
}
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
0
{
455
0
  logdebug(LogHeaders,"---> read slice segment header\n");
456
457
458
  // --- read slice header ---
459
460
0
  slice_segment_header* shdr = new slice_segment_header;
461
0
  bool continueDecoding;
462
0
  de265_error err = shdr->read(&reader,this, &continueDecoding);
463
0
  if (!continueDecoding) {
464
0
    if (img) { img->integrity = INTEGRITY_NOT_DECODED; }
465
0
    nal_parser.free_NAL_unit(nal);
466
0
    delete shdr;
467
0
    return err;
468
0
  }
469
470
0
  if (param_slice_headers_fd>=0) {
471
0
    shdr->dump_slice_segment_header(this, param_slice_headers_fd);
472
0
  }
473
474
475
0
  if (process_slice_segment_header(shdr, &err, nal->pts, &nal_hdr, nal->user_data) == false)
476
0
    {
477
0
      if (img!=nullptr) img->integrity = INTEGRITY_NOT_DECODED;
478
0
      nal_parser.free_NAL_unit(nal);
479
0
      delete shdr;
480
0
      return err;
481
0
    }
482
483
0
  reader.skip_bits(1); // TODO: why?
484
0
  reader.prepare_for_CABAC();
485
486
487
  // modify entry_point_offsets
488
489
0
  uint32_t headerLength = reader.data - nal->data();
490
0
  for (uint32_t i=0;i<shdr->num_entry_point_offsets;i++) {
491
0
    uint32_t skipped = nal->num_skipped_bytes_before(shdr->entry_point_offset[i],
492
0
                                                     headerLength);
493
0
    if (skipped > shdr->entry_point_offset[i]) {
494
0
      add_warning(DE265_WARNING_SLICEHEADER_INVALID, false);
495
0
      nal_parser.free_NAL_unit(nal);
496
0
      delete shdr;
497
0
      return DE265_ERROR_CODED_PARAMETER_OUT_OF_RANGE;
498
0
    }
499
0
    shdr->entry_point_offset[i] -= skipped;
500
0
  }
501
502
  // --- start a new image if this is the first slice ---
503
504
0
  if (shdr->first_slice_segment_in_pic_flag) {
505
0
    image_unit* imgunit = new image_unit;
506
0
    imgunit->img = this->img;
507
0
    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
0
    previous_slice_header = nullptr;
514
0
  }
515
516
517
  // --- add slice to current picture ---
518
519
0
  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
0
    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
0
    previous_slice_header = shdr;
532
533
0
    slice_unit* sliceunit = new slice_unit(this);
534
0
    sliceunit->nal = nal;
535
0
    sliceunit->shdr = shdr;
536
0
    sliceunit->reader = reader;
537
538
0
    sliceunit->flush_reorder_buffer = flush_reorder_buffer_at_this_frame;
539
540
541
0
    image_units.back()->slice_units.push_back(sliceunit);
542
0
  }
543
0
  else {
544
0
    nal_parser.free_NAL_unit(nal);
545
0
    delete shdr;
546
0
  }
547
548
0
  bool did_work;
549
0
  err = decode_some(&did_work);
550
551
0
  return DE265_OK;
552
0
}
553
554
555
template <class T> void pop_front(std::vector<T>& vec)
556
0
{
557
0
  for (size_t i=1;i<vec.size();i++)
558
0
    vec[i-1] = vec[i];
559
560
0
  vec.pop_back();
561
0
}
562
563
564
de265_error decoder_context::decode_some(bool* did_work)
565
0
{
566
0
  de265_error err = DE265_OK;
567
568
0
  *did_work = false;
569
570
0
  if (image_units.empty()) { return DE265_OK; }  // nothing to do
571
572
573
  // decode something if there is work to do
574
575
0
  if ( ! image_units.empty() ) { // && ! image_units[0]->slice_units.empty() ) {
576
577
0
    image_unit* imgunit = image_units[0];
578
0
    slice_unit* sliceunit = imgunit->get_next_unprocessed_slice_segment();
579
580
0
    if (sliceunit != nullptr) {
581
582
      //pop_front(imgunit->slice_units);
583
584
0
      if (sliceunit->flush_reorder_buffer) {
585
0
        dpb.flush_reorder_buffer();
586
0
      }
587
588
0
      *did_work = true;
589
590
      //err = decode_slice_unit_sequential(imgunit, sliceunit);
591
0
      err = decode_slice_unit_parallel(imgunit, sliceunit);
592
0
      if (err) {
593
0
        return err;
594
0
      }
595
596
      //delete sliceunit;
597
0
    }
598
0
  }
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
0
  if ( ( image_units.size()>=2 && image_units[0]->all_slice_segments_processed()) ||
606
0
       ( image_units.size()>=1 && image_units[0]->all_slice_segments_processed() &&
607
0
         nal_parser.number_of_NAL_units_pending()==0 &&
608
0
         (nal_parser.is_end_of_stream() || nal_parser.is_end_of_frame()) )) {
609
610
0
    image_unit* imgunit = image_units[0];
611
612
0
    *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
0
    imgunit->img->mark_all_CTB_progress(CTB_PROGRESS_PREFILTER);
622
623
624
625
    // run post-processing filters (deblocking & SAO)
626
627
0
    if (img->decctx->num_worker_threads)
628
0
      run_postprocessing_filters_parallel(imgunit);
629
0
    else
630
0
      run_postprocessing_filters_sequential(imgunit->img);
631
632
    // process suffix SEIs
633
634
0
    for (size_t i=0;i<imgunit->suffix_SEIs.size();i++) {
635
0
      const sei_message& sei = imgunit->suffix_SEIs[i];
636
637
0
      err = process_sei(&sei, imgunit->img);
638
0
      if (err != DE265_OK)
639
0
        break;
640
0
    }
641
642
643
0
    push_picture_to_output_queue(imgunit);
644
645
    // remove just decoded image unit from queue
646
647
0
    delete imgunit;
648
649
0
    pop_front(image_units);
650
0
  }
651
652
0
  return err;
653
0
}
654
655
656
de265_error decoder_context::decode_slice_unit_sequential(image_unit* imgunit,
657
                                                          slice_unit* sliceunit)
658
0
{
659
0
  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
0
  remove_images_from_dpb(sliceunit->shdr->RemoveReferencesList);
669
670
0
  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
0
  thread_context tctx;
676
677
0
  tctx.shdr = sliceunit->shdr;
678
0
  tctx.img  = imgunit->img;
679
0
  tctx.decctx = this;
680
0
  tctx.imgunit = imgunit;
681
0
  tctx.sliceunit= sliceunit;
682
0
  tctx.CtbAddrInTS = imgunit->img->get_pps().scan->CtbAddrRStoTS[tctx.shdr->slice_segment_address];
683
0
  tctx.task = nullptr;
684
685
0
  init_thread_context(&tctx);
686
687
0
  if (sliceunit->reader.bytes_remaining <= 0) {
688
0
    return DE265_ERROR_PREMATURE_END_OF_SLICE;
689
0
  }
690
691
0
  tctx.cabac_decoder.init(sliceunit->reader.data,
692
0
                         sliceunit->reader.bytes_remaining);
693
694
  // alloc CABAC-model array if entropy_coding_sync is enabled
695
696
0
  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
0
  sliceunit->nThreads=1;
703
704
0
  err=read_slice_segment_data(&tctx);
705
706
0
  sliceunit->finished_threads.set_progress(1);
707
708
0
  return err;
709
0
}
710
711
712
void decoder_context::mark_whole_slice_as_processed(image_unit* imgunit,
713
                                                    slice_unit* sliceunit,
714
                                                    int progress)
715
0
{
716
  //printf("mark whole slice\n");
717
718
719
  // mark all CTBs upto the next slice segment as processed
720
721
0
  slice_unit* nextSegment = imgunit->get_next_slice_segment(sliceunit);
722
0
  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
0
    for (uint32_t ctb=sliceunit->shdr->slice_segment_address;
730
0
         ctb < nextSegment->shdr->slice_segment_address;
731
0
         ctb++)
732
0
      {
733
0
        if (ctb >= imgunit->img->number_of_ctbs())
734
0
          break;
735
736
0
        imgunit->img->ctb_progress[ctb].set_progress(progress);
737
0
      }
738
0
  }
739
0
}
740
741
742
de265_error decoder_context::decode_slice_unit_parallel(image_unit* imgunit,
743
                                                        slice_unit* sliceunit)
744
0
{
745
0
  de265_error err = DE265_OK;
746
747
0
  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
0
  de265_image* img = imgunit->img;
757
0
  const pic_parameter_set& pps = img->get_pps();
758
759
0
  sliceunit->state = slice_unit::InProgress;
760
761
0
  bool use_WPP = (img->decctx->num_worker_threads > 0 &&
762
0
                  pps.entropy_coding_sync_enabled_flag);
763
764
0
  bool use_tiles = (img->decctx->num_worker_threads > 0 &&
765
0
                    pps.tiles_enabled_flag);
766
767
768
  // TODO: remove this warning later when we do frame-parallel decoding
769
0
  if (img->decctx->num_worker_threads > 0 &&
770
0
      pps.entropy_coding_sync_enabled_flag == false &&
771
0
      pps.tiles_enabled_flag == false) {
772
773
0
    img->decctx->add_warning(DE265_WARNING_NO_WPP_CANNOT_USE_MULTITHREADING, true);
774
0
  }
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
0
  if (imgunit->is_first_slice_segment(sliceunit)) {
781
0
    slice_segment_header* shdr = sliceunit->shdr;
782
0
    int firstCTB = shdr->slice_segment_address;
783
784
0
    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
0
  }
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
0
  slice_unit* prevSlice = imgunit->get_prev_slice_segment(sliceunit);
796
  //if (prevSlice) printf("prev slice state: %d\n",prevSlice->state);
797
0
  if (prevSlice && prevSlice->state == slice_unit::Decoded) {
798
0
    mark_whole_slice_as_processed(imgunit,prevSlice,CTB_PROGRESS_PREFILTER);
799
0
  }
800
801
802
  // TODO: even though we cannot split this into several tasks, we should run it
803
  // as a background thread
804
0
  if (!use_WPP && !use_tiles) {
805
    //printf("SEQ\n");
806
0
    err = decode_slice_unit_sequential(imgunit, sliceunit);
807
0
    sliceunit->state = slice_unit::Decoded;
808
0
    mark_whole_slice_as_processed(imgunit,sliceunit,CTB_PROGRESS_PREFILTER);
809
0
    return err;
810
0
  }
811
812
813
0
  if (use_WPP && use_tiles) {
814
    // TODO: this is not allowed ... output some warning or error
815
816
0
    return DE265_WARNING_PPS_HEADER_INVALID;
817
0
  }
818
819
820
0
  if (use_WPP) {
821
    //printf("WPP\n");
822
0
    err = decode_slice_unit_WPP(imgunit, sliceunit);
823
0
    sliceunit->state = slice_unit::Decoded;
824
0
    mark_whole_slice_as_processed(imgunit,sliceunit,CTB_PROGRESS_PREFILTER);
825
0
    return err;
826
0
  }
827
0
  else if (use_tiles) {
828
    //printf("TILE\n");
829
0
    err = decode_slice_unit_tiles(imgunit, sliceunit);
830
0
    sliceunit->state = slice_unit::Decoded;
831
0
    mark_whole_slice_as_processed(imgunit,sliceunit,CTB_PROGRESS_PREFILTER);
832
0
    return err;
833
0
  }
834
835
0
  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
0
{
843
0
  de265_error err = DE265_OK;
844
845
0
  de265_image* img = imgunit->img;
846
0
  slice_segment_header* shdr = sliceunit->shdr;
847
0
  const pic_parameter_set& pps = img->get_pps();
848
849
0
  uint16_t nRows = shdr->num_entry_point_offsets +1;
850
0
  uint16_t ctbsWidth = img->get_sps().PicWidthInCtbsY;
851
852
853
0
  assert(img->num_threads_active() == 0);
854
855
856
  // reserve space to store entropy coding context models for each CTB row
857
858
0
  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
0
    imgunit->ctx_models.resize( (img->get_sps().PicHeightInCtbsY-1) ); //* CONTEXT_MODEL_TABLE_LENGTH );
861
0
    imgunit->StatCoeff_models.assign( (img->get_sps().PicHeightInCtbsY-1), {{0,0,0,0}} );
862
0
  }
863
864
865
0
  sliceunit->allocate_thread_contexts(nRows);
866
867
868
  // first CTB in this slice
869
0
  uint32_t ctbAddrRS = shdr->slice_segment_address;
870
0
  uint16_t ctbRow    = ctbAddrRS / ctbsWidth;
871
872
0
  if (ctbRow + nRows > img->get_sps().PicHeightInCtbsY) {
873
0
    return DE265_WARNING_SLICEHEADER_INVALID;
874
0
  }
875
876
0
  for (uint16_t entryPt=0;entryPt<nRows;entryPt++) {
877
    // entry points other than the first start at CTB rows
878
0
    if (entryPt>0) {
879
0
      ctbRow++;
880
0
      ctbAddrRS = ctbRow * ctbsWidth;
881
0
    }
882
0
    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
0
      err = DE265_WARNING_SLICEHEADER_INVALID;
889
0
      break;
890
0
    }
891
892
893
    // prepare thread context
894
895
0
    thread_context* tctx = sliceunit->get_thread_context(entryPt);
896
897
0
    tctx->shdr    = shdr;
898
0
    tctx->decctx  = img->decctx;
899
0
    tctx->img     = img;
900
0
    tctx->imgunit = imgunit;
901
0
    tctx->sliceunit= sliceunit;
902
903
0
    if (ctbAddrRS >= pps.scan->CtbAddrRStoTS.size()) {
904
0
      err = DE265_WARNING_SLICEHEADER_INVALID;
905
0
      break;
906
0
    }
907
0
    tctx->CtbAddrInTS = pps.scan->CtbAddrRStoTS[ctbAddrRS];
908
909
0
    init_thread_context(tctx);
910
911
912
    // init CABAC
913
914
0
    int dataStartIndex;
915
0
    if (entryPt==0) { dataStartIndex=0; }
916
0
    else            { dataStartIndex=shdr->entry_point_offset[entryPt-1]; }
917
918
0
    int dataEnd;
919
0
    if (entryPt==nRows-1) dataEnd = sliceunit->reader.bytes_remaining;
920
0
    else                  dataEnd = shdr->entry_point_offset[entryPt];
921
922
0
    if (dataStartIndex<0 || dataEnd>sliceunit->reader.bytes_remaining ||
923
0
        dataEnd <= dataStartIndex) {
924
      //printf("WPP premature end\n");
925
0
      err = DE265_ERROR_PREMATURE_END_OF_SLICE;
926
0
      break;
927
0
    }
928
929
0
    tctx->cabac_decoder.init(&sliceunit->reader.data[dataStartIndex],
930
0
                             dataEnd-dataStartIndex);
931
932
    // add task
933
934
    //printf("start task for ctb-row: %d\n",ctbRow);
935
0
    img->thread_start(1);
936
0
    sliceunit->nThreads++;
937
0
    add_task_decode_CTB_row(tctx, entryPt==0, ctbRow);
938
0
  }
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
0
  img->wait_for_completion();
955
956
0
  for (size_t i=0;i<imgunit->tasks.size();i++)
957
0
    delete imgunit->tasks[i];
958
0
  imgunit->tasks.clear();
959
960
0
  return err;
961
0
}
962
963
de265_error decoder_context::decode_slice_unit_tiles(image_unit* imgunit,
964
                                                     slice_unit* sliceunit)
965
0
{
966
0
  de265_error err = DE265_OK;
967
968
0
  de265_image* img = imgunit->img;
969
0
  slice_segment_header* shdr = sliceunit->shdr;
970
0
  const pic_parameter_set& pps = img->get_pps();
971
972
0
  uint16_t nTiles = shdr->num_entry_point_offsets +1;
973
0
  uint16_t ctbsWidth = img->get_sps().PicWidthInCtbsY;
974
975
976
0
  assert(img->num_threads_active() == 0);
977
978
0
  sliceunit->allocate_thread_contexts(nTiles);
979
980
981
  // first CTB in this slice
982
0
  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
0
  if (ctbAddrRS >= pps.scan->CtbAddrRStoTS.size()) {
987
0
    return DE265_WARNING_SLICEHEADER_INVALID;
988
0
  }
989
0
  int tileID = pps.scan->TileIdRS[ctbAddrRS];
990
991
0
  for (uint16_t entryPt=0;entryPt<nTiles;entryPt++) {
992
    // entry points other than the first start at tile beginnings
993
0
    if (entryPt>0) {
994
0
      tileID++;
995
996
0
      if (tileID >= pps.num_tile_columns * pps.num_tile_rows) {
997
0
        err = DE265_WARNING_SLICEHEADER_INVALID;
998
0
        break;
999
0
      }
1000
1001
0
      uint16_t ctbX = pps.colBd[tileID % pps.num_tile_columns];
1002
0
      uint16_t ctbY = pps.rowBd[tileID / pps.num_tile_columns];
1003
0
      ctbAddrRS = ctbY * ctbsWidth + ctbX;
1004
1005
0
      if (ctbAddrRS >= pps.scan->CtbAddrRStoTS.size()) {
1006
0
        err = DE265_WARNING_SLICEHEADER_INVALID;
1007
0
        break;
1008
0
      }
1009
0
    }
1010
1011
    // set thread context
1012
1013
0
    thread_context* tctx = sliceunit->get_thread_context(entryPt);
1014
1015
0
    tctx->shdr   = shdr;
1016
0
    tctx->decctx = img->decctx;
1017
0
    tctx->img    = img;
1018
0
    tctx->imgunit = imgunit;
1019
0
    tctx->sliceunit= sliceunit;
1020
0
    tctx->CtbAddrInTS = pps.scan->CtbAddrRStoTS[ctbAddrRS];
1021
1022
0
    init_thread_context(tctx);
1023
1024
1025
    // init CABAC
1026
1027
0
    int dataStartIndex;
1028
0
    if (entryPt==0) { dataStartIndex=0; }
1029
0
    else            { dataStartIndex=shdr->entry_point_offset[entryPt-1]; }
1030
1031
0
    int dataEnd;
1032
0
    if (entryPt==nTiles-1) dataEnd = sliceunit->reader.bytes_remaining;
1033
0
    else                   dataEnd = shdr->entry_point_offset[entryPt];
1034
1035
0
    if (dataStartIndex<0 || dataEnd>sliceunit->reader.bytes_remaining ||
1036
0
        dataEnd <= dataStartIndex) {
1037
0
      err = DE265_ERROR_PREMATURE_END_OF_SLICE;
1038
0
      break;
1039
0
    }
1040
1041
0
    tctx->cabac_decoder.init(&sliceunit->reader.data[dataStartIndex],
1042
0
                             dataEnd-dataStartIndex);
1043
1044
    // add task
1045
1046
    //printf("add tiles thread\n");
1047
0
    img->thread_start(1);
1048
0
    sliceunit->nThreads++;
1049
0
    add_task_decode_slice_segment(tctx, entryPt==0,
1050
0
                                  static_cast<uint16_t>(ctbAddrRS % ctbsWidth),
1051
0
                                  static_cast<uint16_t>(ctbAddrRS / ctbsWidth));
1052
0
  }
1053
1054
0
  img->wait_for_completion();
1055
1056
0
  for (size_t i=0;i<imgunit->tasks.size();i++)
1057
0
    delete imgunit->tasks[i];
1058
0
  imgunit->tasks.clear();
1059
1060
0
  return err;
1061
0
}
1062
1063
1064
de265_error decoder_context::decode_NAL(NAL_unit* nal)
1065
0
{
1066
  //return decode_NAL_OLD(nal);
1067
1068
0
  decoder_context* ctx = this;
1069
1070
0
  de265_error err = DE265_OK;
1071
1072
0
  bitreader reader(nal->data(), nal->size());
1073
1074
0
  nal_header nal_hdr;
1075
0
  err = nal_hdr.read(&reader);
1076
0
  if (err != DE265_OK) {
1077
0
    nal_parser.free_NAL_unit(nal);
1078
0
    return err;
1079
0
  }
1080
0
  ctx->process_nal_hdr(&nal_hdr);
1081
1082
0
  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
0
    nal_parser.free_NAL_unit(nal);
1086
0
    return DE265_OK;
1087
0
  }
1088
1089
0
  loginfo(LogHighlevel,"NAL: 0x%x 0x%x -  unit type:%s temporal id:%d\n",
1090
0
          nal->data()[0], nal->data()[1],
1091
0
          get_NAL_name(nal_hdr.nal_unit_type),
1092
0
          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
0
  if (nal_hdr.nuh_temporal_id > current_HighestTid) {
1107
0
    nal_parser.free_NAL_unit(nal);
1108
0
    return DE265_OK;
1109
0
  }
1110
1111
1112
0
  if (nal_hdr.nal_unit_type<32) {
1113
0
    err = read_slice_NAL(reader, nal, nal_hdr);
1114
0
  }
1115
0
  else switch (nal_hdr.nal_unit_type) {
1116
0
    case NAL_UNIT_VPS_NUT:
1117
0
      err = read_vps_NAL(reader);
1118
0
      nal_parser.free_NAL_unit(nal);
1119
0
      break;
1120
1121
0
    case NAL_UNIT_SPS_NUT:
1122
0
      err = read_sps_NAL(reader);
1123
0
      nal_parser.free_NAL_unit(nal);
1124
0
      break;
1125
1126
0
    case NAL_UNIT_PPS_NUT:
1127
0
      err = read_pps_NAL(reader);
1128
0
      nal_parser.free_NAL_unit(nal);
1129
0
      break;
1130
1131
0
    case NAL_UNIT_PREFIX_SEI_NUT:
1132
0
    case NAL_UNIT_SUFFIX_SEI_NUT:
1133
0
      err = read_sei_NAL(reader, nal_hdr.nal_unit_type==NAL_UNIT_SUFFIX_SEI_NUT);
1134
0
      nal_parser.free_NAL_unit(nal);
1135
0
      break;
1136
1137
0
    case NAL_UNIT_EOS_NUT:
1138
0
      ctx->FirstAfterEndOfSequenceNAL = true;
1139
0
      nal_parser.free_NAL_unit(nal);
1140
0
      break;
1141
1142
0
    default:
1143
0
      nal_parser.free_NAL_unit(nal);
1144
0
      break;
1145
0
    }
1146
1147
0
  return err;
1148
0
}
1149
1150
1151
de265_error decoder_context::decode(int* more)
1152
0
{
1153
0
  decoder_context* ctx = this;
1154
1155
  // if the stream has ended, and no more NALs are to be decoded, flush all pictures
1156
1157
0
  if (ctx->nal_parser.get_NAL_queue_length() == 0 &&
1158
0
      (ctx->nal_parser.is_end_of_stream() || ctx->nal_parser.is_end_of_frame()) &&
1159
0
      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
0
    ctx->dpb.flush_reorder_buffer();
1165
1166
0
    if (more) { *more = ctx->dpb.num_pictures_in_output_queue(); }
1167
1168
0
    return DE265_OK;
1169
0
  }
1170
1171
1172
  // if NAL-queue is empty, we need more data
1173
  // -> input stalled
1174
1175
0
  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
0
  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
0
  de265_error err = DE265_OK;
1196
0
  bool did_work = false;
1197
1198
0
  if (ctx->nal_parser.get_NAL_queue_length()) { // number_of_NAL_units_pending()) {
1199
0
    NAL_unit* nal = ctx->nal_parser.pop_from_NAL_queue();
1200
0
    assert(nal);
1201
0
    err = ctx->decode_NAL(nal);
1202
    // ctx->nal_parser.free_NAL_unit(nal); TODO: do not free NAL with new loop
1203
0
    did_work=true;
1204
0
  }
1205
0
  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
0
  else {
1212
0
    err = decode_some(&did_work);
1213
0
  }
1214
1215
0
  if (more) {
1216
    // decoding error is assumed to be unrecoverable
1217
0
    *more = (err==DE265_OK && did_work);
1218
0
  }
1219
1220
0
  return err;
1221
0
}
1222
1223
1224
void decoder_context::process_nal_hdr(nal_header* nal)
1225
0
{
1226
0
  nal_unit_type = nal->nal_unit_type;
1227
1228
0
  IdrPicFlag = isIdrPic(nal->nal_unit_type);
1229
0
  RapPicFlag = isRapPic(nal->nal_unit_type);
1230
0
}
1231
1232
1233
1234
/* 8.3.1
1235
 */
1236
void decoder_context::process_picture_order_count(slice_segment_header* hdr)
1237
0
{
1238
0
  loginfo(LogHeaders,"POC computation. lsb:%d prev.pic.lsb:%d msb:%d\n",
1239
0
          hdr->slice_pic_order_cnt_lsb,
1240
0
          prevPicOrderCntLsb,
1241
0
          PicOrderCntMsb);
1242
1243
0
  if (isIRAP(nal_unit_type) &&
1244
0
      NoRaslOutputFlag)
1245
0
    {
1246
0
      PicOrderCntMsb=0;
1247
1248
1249
      // flush all images from reorder buffer
1250
1251
0
      flush_reorder_buffer_at_this_frame = true;
1252
      //ctx->dpb.flush_reorder_buffer();
1253
0
    }
1254
0
  else
1255
0
    {
1256
0
      int MaxPicOrderCntLsb = current_sps->MaxPicOrderCntLsb;
1257
1258
0
      if ((hdr->slice_pic_order_cnt_lsb < prevPicOrderCntLsb) &&
1259
0
          (prevPicOrderCntLsb - hdr->slice_pic_order_cnt_lsb) >= MaxPicOrderCntLsb/2) {
1260
0
        PicOrderCntMsb = prevPicOrderCntMsb + MaxPicOrderCntLsb;
1261
0
      }
1262
0
      else if ((hdr->slice_pic_order_cnt_lsb > prevPicOrderCntLsb) &&
1263
0
               (hdr->slice_pic_order_cnt_lsb - prevPicOrderCntLsb) > MaxPicOrderCntLsb/2) {
1264
0
        PicOrderCntMsb = prevPicOrderCntMsb - MaxPicOrderCntLsb;
1265
0
      }
1266
0
      else {
1267
0
        PicOrderCntMsb = prevPicOrderCntMsb;
1268
0
      }
1269
0
    }
1270
1271
0
  img->PicOrderCntVal = PicOrderCntMsb + hdr->slice_pic_order_cnt_lsb;
1272
0
  img->picture_order_cnt_lsb = hdr->slice_pic_order_cnt_lsb;
1273
1274
0
  loginfo(LogHeaders,"POC computation. new msb:%d POC=%d\n",
1275
0
          PicOrderCntMsb,
1276
0
          img->PicOrderCntVal);
1277
1278
0
  if (img->nal_hdr.nuh_temporal_id==0 &&
1279
0
      !isSublayerNonReference(nal_unit_type) &&
1280
0
      !isRASL(nal_unit_type) &&
1281
0
      !isRADL(nal_unit_type))
1282
0
    {
1283
0
      loginfo(LogHeaders,"set prevPicOrderCntLsb/Msb\n");
1284
1285
0
      prevPicOrderCntLsb = hdr->slice_pic_order_cnt_lsb;
1286
0
      prevPicOrderCntMsb = PicOrderCntMsb;
1287
0
    }
1288
0
}
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
0
{
1297
0
  assert(dpb.has_free_dpb_picture(true));
1298
1299
0
  std::shared_ptr<const seq_parameter_set> current_sps = this->sps[ (int)current_pps->seq_parameter_set_id ];
1300
1301
0
  int idx = dpb.new_image(current_sps, this, 0,0, false);
1302
0
  if (idx<0) {
1303
0
    return idx;
1304
0
  }
1305
1306
0
  de265_image* img = dpb.get_image(idx);
1307
1308
0
  img->fill_image(1<<(sps->BitDepth_Y-1),
1309
0
                  1<<(sps->BitDepth_C-1),
1310
0
                  1<<(sps->BitDepth_C-1));
1311
1312
0
  img->fill_pred_mode(MODE_INTRA);
1313
1314
0
  img->PicOrderCntVal = POC;
1315
0
  img->picture_order_cnt_lsb = POC & (sps->MaxPicOrderCntLsb-1);
1316
0
  img->PicOutputFlag = false;
1317
0
  img->PicState = (longTerm ? UsedForLongTermReference : UsedForShortTermReference);
1318
0
  img->integrity = INTEGRITY_UNAVAILABLE_REFERENCE;
1319
1320
0
  return idx;
1321
0
}
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
0
{
1330
0
  std::vector<int> removeReferencesList;
1331
1332
0
  const uint32_t currentID = img->get_ID();
1333
1334
1335
0
  if (isIRAP(nal_unit_type) && NoRaslOutputFlag) {
1336
1337
0
    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
0
    for (size_t i=0;i<dpb.size();i++) {
1351
0
      de265_image* img = dpb.get_image(i);
1352
1353
0
      if (img->PicState != UnusedForReference &&
1354
0
          img->PicOrderCntVal < currentPOC &&
1355
0
          img->removed_at_picture_id > img->get_ID()) {
1356
1357
0
        removeReferencesList.push_back(img->get_ID());
1358
0
        img->removed_at_picture_id = img->get_ID();
1359
1360
        //printf("will remove ID %d (a)\n",img->get_ID());
1361
0
      }
1362
0
    }
1363
0
  }
1364
1365
1366
0
  if (isIDR(nal_unit_type)) {
1367
1368
    // clear all reference pictures
1369
1370
0
    NumPocStCurrBefore = 0;
1371
0
    NumPocStCurrAfter = 0;
1372
0
    NumPocStFoll = 0;
1373
0
    NumPocLtCurr = 0;
1374
0
    NumPocLtFoll = 0;
1375
0
  }
1376
0
  else {
1377
0
    const ref_pic_set* rps = &hdr->CurrRps;
1378
1379
    // (8-98)
1380
1381
0
    int i,j,k;
1382
1383
    // scan ref-pic-set for smaller POCs and fill into PocStCurrBefore / PocStFoll
1384
1385
0
    for (i=0, j=0, k=0;
1386
0
         i<rps->NumNegativePics;
1387
0
         i++)
1388
0
      {
1389
0
        if (rps->UsedByCurrPicS0[i]) {
1390
0
          PocStCurrBefore[j++] = img->PicOrderCntVal + rps->DeltaPocS0[i];
1391
          //printf("PocStCurrBefore = %d\n",PocStCurrBefore[j-1]);
1392
0
        }
1393
0
        else {
1394
0
          PocStFoll[k++] = img->PicOrderCntVal + rps->DeltaPocS0[i];
1395
0
        }
1396
0
      }
1397
1398
0
    NumPocStCurrBefore = j;
1399
1400
1401
    // scan ref-pic-set for larger POCs and fill into PocStCurrAfter / PocStFoll
1402
1403
0
    for (i=0, j=0;
1404
0
         i<rps->NumPositivePics;
1405
0
         i++)
1406
0
      {
1407
0
        if (rps->UsedByCurrPicS1[i]) {
1408
0
          PocStCurrAfter[j++] = img->PicOrderCntVal + rps->DeltaPocS1[i];
1409
          //printf("PocStCurrAfter = %d\n",PocStCurrAfter[j-1]);
1410
0
        }
1411
0
        else {
1412
0
          PocStFoll[k++] = img->PicOrderCntVal + rps->DeltaPocS1[i];
1413
0
        }
1414
0
      }
1415
1416
0
    NumPocStCurrAfter = j;
1417
0
    NumPocStFoll = k;
1418
1419
1420
    // find used / future long-term references
1421
1422
0
    for (i=0, j=0, k=0;
1423
         //i<current_sps->num_long_term_ref_pics_sps + hdr->num_long_term_pics;
1424
0
         i<hdr->num_long_term_sps + hdr->num_long_term_pics;
1425
0
         i++)
1426
0
      {
1427
0
        int pocLt = PocLsbLt[i];
1428
1429
0
        if (hdr->delta_poc_msb_present_flag[i]) {
1430
0
          int currentPictureMSB = img->PicOrderCntVal - hdr->slice_pic_order_cnt_lsb;
1431
0
          if (DeltaPocMsbCycleLt[i] > static_cast<uint32_t>(INT32_MAX) / current_sps->MaxPicOrderCntLsb) {
1432
0
            add_warning(DE265_WARNING_SLICEHEADER_INVALID, false);
1433
0
            return DE265_ERROR_CODED_PARAMETER_OUT_OF_RANGE;
1434
0
          }
1435
0
          pocLt += currentPictureMSB
1436
0
            - static_cast<int>(DeltaPocMsbCycleLt[i] * current_sps->MaxPicOrderCntLsb);
1437
0
        }
1438
1439
0
        if (UsedByCurrPicLt[i]) {
1440
0
          PocLtCurr[j] = pocLt;
1441
0
          CurrDeltaPocMsbPresentFlag[j] = hdr->delta_poc_msb_present_flag[i];
1442
0
          j++;
1443
0
        }
1444
0
        else {
1445
0
          PocLtFoll[k] = pocLt;
1446
0
          FollDeltaPocMsbPresentFlag[k] = hdr->delta_poc_msb_present_flag[i];
1447
0
          k++;
1448
0
        }
1449
0
      }
1450
1451
0
    NumPocLtCurr = j;
1452
0
    NumPocLtFoll = k;
1453
0
  }
1454
1455
1456
  // (old 8-99) / (new 8-106)
1457
  // 1.
1458
1459
0
  std::vector<char> picInAnyList(dpb.size(), false);
1460
1461
1462
0
  dpb.log_dpb_content();
1463
1464
0
  for (int i=0;i<NumPocLtCurr;i++) {
1465
0
    int k;
1466
0
    if (!CurrDeltaPocMsbPresentFlag[i]) {
1467
0
      k = dpb.DPB_index_of_picture_with_LSB(PocLtCurr[i], currentID, true);
1468
0
    }
1469
0
    else {
1470
0
      k = dpb.DPB_index_of_picture_with_POC(PocLtCurr[i], currentID, true);
1471
0
    }
1472
1473
0
    RefPicSetLtCurr[i] = k; // -1 == "no reference picture"
1474
0
    if (k>=0) picInAnyList[k]=true;
1475
0
    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
0
      int concealedPicture = generate_unavailable_reference_picture(current_sps.get(),
1479
0
                                                                    PocLtCurr[i], true);
1480
0
      if (concealedPicture<0) {
1481
0
        return (de265_error)(-concealedPicture);
1482
0
      }
1483
0
      picInAnyList.resize(dpb.size(), false); // adjust size of array to hold new picture
1484
1485
0
      RefPicSetLtCurr[i] = k = concealedPicture;
1486
0
      picInAnyList[concealedPicture]=true;
1487
0
    }
1488
1489
0
    if (dpb.get_image(k)->integrity != INTEGRITY_CORRECT) {
1490
0
      img->integrity = INTEGRITY_DERIVED_FROM_FAULTY_REFERENCE;
1491
0
    }
1492
0
  }
1493
1494
1495
0
  for (int i=0;i<NumPocLtFoll;i++) {
1496
0
    int k;
1497
0
    if (!FollDeltaPocMsbPresentFlag[i]) {
1498
0
      k = dpb.DPB_index_of_picture_with_LSB(PocLtFoll[i], currentID, true);
1499
0
    }
1500
0
    else {
1501
0
      k = dpb.DPB_index_of_picture_with_POC(PocLtFoll[i], currentID, true);
1502
0
    }
1503
1504
0
    RefPicSetLtFoll[i] = k; // -1 == "no reference picture"
1505
0
    if (k>=0) picInAnyList[k]=true;
1506
0
    else {
1507
0
      int concealedPicture = k = generate_unavailable_reference_picture(current_sps.get(),
1508
0
                                                                        PocLtFoll[i], true);
1509
0
      if (concealedPicture<0) {
1510
0
        return (de265_error)(-concealedPicture);
1511
0
      }
1512
0
      picInAnyList.resize(dpb.size(), false); // adjust size of array to hold new picture
1513
1514
0
      RefPicSetLtFoll[i] = concealedPicture;
1515
0
      picInAnyList[concealedPicture]=true;
1516
0
    }
1517
0
  }
1518
1519
1520
  // 2. Mark all pictures in RefPicSetLtCurr / RefPicSetLtFoll as UsedForLongTermReference
1521
1522
0
  for (int i=0;i<NumPocLtCurr;i++) {
1523
0
    dpb.get_image(RefPicSetLtCurr[i])->PicState = UsedForLongTermReference;
1524
0
  }
1525
1526
0
  for (int i=0;i<NumPocLtFoll;i++) {
1527
0
    dpb.get_image(RefPicSetLtFoll[i])->PicState = UsedForLongTermReference;
1528
0
  }
1529
1530
1531
  // 3.
1532
1533
0
  for (int i=0;i<NumPocStCurrBefore;i++) {
1534
0
    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
0
    RefPicSetStCurrBefore[i] = k; // -1 == "no reference picture"
1539
0
    if (k>=0) picInAnyList[k]=true;
1540
0
    else {
1541
0
      int concealedPicture = generate_unavailable_reference_picture(current_sps.get(),
1542
0
                                                                    PocStCurrBefore[i], false);
1543
0
      if (concealedPicture<0) {
1544
0
        return (de265_error)(-concealedPicture);
1545
0
      }
1546
0
      RefPicSetStCurrBefore[i] = k = concealedPicture;
1547
1548
0
      picInAnyList.resize(dpb.size(), false); // adjust size of array to hold new picture
1549
0
      picInAnyList[concealedPicture] = true;
1550
1551
      //printf("  concealed: %d\n", concealedPicture);
1552
0
    }
1553
1554
0
    if (dpb.get_image(k)->integrity != INTEGRITY_CORRECT) {
1555
0
      img->integrity = INTEGRITY_DERIVED_FROM_FAULTY_REFERENCE;
1556
0
    }
1557
0
  }
1558
1559
0
  for (int i=0;i<NumPocStCurrAfter;i++) {
1560
0
    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
0
    RefPicSetStCurrAfter[i] = k; // -1 == "no reference picture"
1565
0
    if (k>=0) picInAnyList[k]=true;
1566
0
    else {
1567
0
      int concealedPicture = generate_unavailable_reference_picture(current_sps.get(),
1568
0
                                                                    PocStCurrAfter[i], false);
1569
0
      if (concealedPicture<0) {
1570
0
        return (de265_error)(-concealedPicture);
1571
0
      }
1572
0
      RefPicSetStCurrAfter[i] = k = concealedPicture;
1573
1574
1575
0
      picInAnyList.resize(dpb.size(), false); // adjust size of array to hold new picture
1576
0
      picInAnyList[concealedPicture]=true;
1577
1578
      //printf("  concealed: %d\n", concealedPicture);
1579
0
    }
1580
1581
0
    if (dpb.get_image(k)->integrity != INTEGRITY_CORRECT) {
1582
0
      img->integrity = INTEGRITY_DERIVED_FROM_FAULTY_REFERENCE;
1583
0
    }
1584
0
  }
1585
1586
0
  for (int i=0;i<NumPocStFoll;i++) {
1587
0
    int k = dpb.DPB_index_of_picture_with_POC(PocStFoll[i], currentID);
1588
    // if (k<0) { assert(false); } // IGNORE
1589
1590
0
    RefPicSetStFoll[i] = k; // -1 == "no reference picture"
1591
0
    if (k>=0) picInAnyList[k]=true;
1592
0
  }
1593
1594
  // 4. any picture that is not marked for reference is put into the "UnusedForReference" state
1595
1596
0
  for (size_t i=0;i<dpb.size();i++)
1597
0
    if (i>=picInAnyList.size() || !picInAnyList[i])        // no reference
1598
0
      {
1599
0
        de265_image* dpbimg = dpb.get_image(i);
1600
0
        if (dpbimg != img &&  // not the current picture
1601
0
            dpbimg->removed_at_picture_id > img->get_ID()) // has not been removed before
1602
0
          {
1603
0
            if (dpbimg->PicState != UnusedForReference) {
1604
0
              removeReferencesList.push_back(dpbimg->get_ID());
1605
              //printf("will remove ID %d (b)\n",dpbimg->get_ID());
1606
1607
0
              dpbimg->removed_at_picture_id = img->get_ID();
1608
0
            }
1609
0
          }
1610
0
      }
1611
1612
0
  hdr->RemoveReferencesList = removeReferencesList;
1613
1614
  //remove_images_from_dpb(hdr->RemoveReferencesList);
1615
1616
0
  return DE265_OK;
1617
0
}
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
0
{
1631
0
  int NumPocTotalCurr = hdr->NumPocTotalCurr;
1632
0
  int NumRpsCurrTempList0 = std::max((int)hdr->num_ref_idx_l0_active, NumPocTotalCurr);
1633
1634
  // TODO: fold code for both lists together
1635
1636
0
  int RefPicListTemp0[3*MAX_NUM_REF_PICS]; // TODO: what would be the correct maximum ?
1637
0
  int RefPicListTemp1[3*MAX_NUM_REF_PICS]; // TODO: what would be the correct maximum ?
1638
0
  char isLongTerm[2][3*MAX_NUM_REF_PICS];
1639
1640
0
  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
0
  int rIdx=0;
1649
0
  while (rIdx < NumRpsCurrTempList0) {
1650
0
    for (int i=0;i<NumPocStCurrBefore && rIdx<NumRpsCurrTempList0; rIdx++,i++)
1651
0
      RefPicListTemp0[rIdx] = RefPicSetStCurrBefore[i];
1652
1653
0
    for (int i=0;i<NumPocStCurrAfter && rIdx<NumRpsCurrTempList0; rIdx++,i++)
1654
0
      RefPicListTemp0[rIdx] = RefPicSetStCurrAfter[i];
1655
1656
0
    for (int i=0;i<NumPocLtCurr && rIdx<NumRpsCurrTempList0; rIdx++,i++) {
1657
0
      RefPicListTemp0[rIdx] = RefPicSetLtCurr[i];
1658
0
      isLongTerm[0][rIdx] = true;
1659
0
    }
1660
1661
    // This check is to prevent an endless loop when no images are added above.
1662
0
    if (rIdx==0) {
1663
0
      add_warning(DE265_WARNING_FAULTY_REFERENCE_PICTURE_LIST, false);
1664
0
      return false;
1665
0
    }
1666
0
  }
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
0
  assert(hdr->num_ref_idx_l0_active <= 16);
1676
0
  for (rIdx=0; rIdx<hdr->num_ref_idx_l0_active; rIdx++) {
1677
0
    int idx = hdr->ref_pic_list_modification_flag_l0 ? hdr->list_entry_l0[rIdx] : rIdx;
1678
1679
0
    if (idx >= NumRpsCurrTempList0) {
1680
0
      add_warning(DE265_WARNING_FAULTY_REFERENCE_PICTURE_LIST, false);
1681
0
      return false;
1682
0
    }
1683
1684
0
    hdr->RefPicList[0][rIdx] = RefPicListTemp0[idx];
1685
0
    hdr->LongTermRefPic[0][rIdx] = isLongTerm[0][idx];
1686
1687
    // remember POC of referenced image (needed in motion.c, derive_collocated_motion_vector)
1688
0
    de265_image* img_0_rIdx = dpb.get_image(hdr->RefPicList[0][rIdx]);
1689
0
    if (img_0_rIdx==nullptr) {
1690
0
      return false;
1691
0
    }
1692
0
    hdr->RefPicList_POC[0][rIdx] = img_0_rIdx->PicOrderCntVal;
1693
0
    hdr->RefPicList_PicState[0][rIdx] = img_0_rIdx->PicState;
1694
0
  }
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
0
  if (hdr->slice_type == SLICE_TYPE_B) {
1704
0
    int NumRpsCurrTempList1 = std::max((int)hdr->num_ref_idx_l1_active, NumPocTotalCurr);
1705
1706
0
    int rIdx=0;
1707
0
    while (rIdx < NumRpsCurrTempList1) {
1708
0
      for (int i=0;i<NumPocStCurrAfter && rIdx<NumRpsCurrTempList1; rIdx++,i++) {
1709
0
        RefPicListTemp1[rIdx] = RefPicSetStCurrAfter[i];
1710
0
      }
1711
1712
0
      for (int i=0;i<NumPocStCurrBefore && rIdx<NumRpsCurrTempList1; rIdx++,i++) {
1713
0
        RefPicListTemp1[rIdx] = RefPicSetStCurrBefore[i];
1714
0
      }
1715
1716
0
      for (int i=0;i<NumPocLtCurr && rIdx<NumRpsCurrTempList1; rIdx++,i++) {
1717
0
        RefPicListTemp1[rIdx] = RefPicSetLtCurr[i];
1718
0
        isLongTerm[1][rIdx] = true;
1719
0
      }
1720
1721
      // This check is to prevent an endless loop when no images are added above.
1722
0
      if (rIdx==0) {
1723
0
        add_warning(DE265_WARNING_FAULTY_REFERENCE_PICTURE_LIST, false);
1724
0
        return false;
1725
0
      }
1726
0
    }
1727
1728
0
    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
0
    assert(hdr->num_ref_idx_l1_active <= 16);
1734
0
    for (rIdx=0; rIdx<hdr->num_ref_idx_l1_active; rIdx++) {
1735
0
      int idx = hdr->ref_pic_list_modification_flag_l1 ? hdr->list_entry_l1[rIdx] : rIdx;
1736
1737
0
      if (idx >= NumRpsCurrTempList1) {
1738
0
        add_warning(DE265_WARNING_FAULTY_REFERENCE_PICTURE_LIST, false);
1739
0
        return false;
1740
0
      }
1741
1742
0
      hdr->RefPicList[1][rIdx] = RefPicListTemp1[idx];
1743
0
      hdr->LongTermRefPic[1][rIdx] = isLongTerm[1][idx];
1744
1745
      // remember POC of referenced imaged (needed in motion.c, derive_collocated_motion_vector)
1746
0
      de265_image* img_1_rIdx = dpb.get_image(hdr->RefPicList[1][rIdx]);
1747
0
      if (img_1_rIdx == nullptr) { return false; }
1748
0
      hdr->RefPicList_POC[1][rIdx] = img_1_rIdx->PicOrderCntVal;
1749
0
      hdr->RefPicList_PicState[1][rIdx] = img_1_rIdx->PicState;
1750
0
    }
1751
0
  }
1752
1753
1754
  // show reference picture lists
1755
1756
0
  loginfo(LogHeaders,"RefPicList[0] =");
1757
0
  for (rIdx=0; rIdx<hdr->num_ref_idx_l0_active; rIdx++) {
1758
0
    loginfo(LogHeaders,"* [%d]=%d (LT=%d)",
1759
0
            hdr->RefPicList[0][rIdx],
1760
0
            hdr->RefPicList_POC[0][rIdx],
1761
0
            hdr->LongTermRefPic[0][rIdx]
1762
0
            );
1763
0
  }
1764
0
  loginfo(LogHeaders,"*\n");
1765
1766
0
  if (hdr->slice_type == SLICE_TYPE_B) {
1767
0
    loginfo(LogHeaders,"RefPicList[1] =");
1768
0
    for (rIdx=0; rIdx<hdr->num_ref_idx_l1_active; rIdx++) {
1769
0
      loginfo(LogHeaders,"* [%d]=%d (LT=%d)",
1770
0
              hdr->RefPicList[1][rIdx],
1771
0
              hdr->RefPicList_POC[1][rIdx],
1772
0
              hdr->LongTermRefPic[1][rIdx]
1773
0
              );
1774
0
    }
1775
0
    loginfo(LogHeaders,"*\n");
1776
0
  }
1777
1778
0
  return true;
1779
0
}
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
0
{
1813
0
  de265_image* img = imgunit->img;
1814
1815
0
  int saoWaitsForProgress = CTB_PROGRESS_PREFILTER;
1816
0
  bool waitForCompletion = false;
1817
1818
0
  if (!img->decctx->param_disable_deblocking) {
1819
0
    add_deblocking_tasks(imgunit);
1820
0
    saoWaitsForProgress = CTB_PROGRESS_DEBLK_H;
1821
0
  }
1822
1823
0
  if (!img->decctx->param_disable_sao) {
1824
0
    waitForCompletion |= add_sao_tasks(imgunit, saoWaitsForProgress);
1825
    //apply_sample_adaptive_offset(img);
1826
0
  }
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
0
  (void)waitForCompletion;
1831
1832
0
  img->wait_for_completion();
1833
0
}
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
0
{
1844
0
  de265_image* outimg = imgunit->img;
1845
1846
0
  if (outimg==nullptr) { return DE265_OK; }
1847
1848
1849
  // push image into output queue
1850
1851
0
  if (outimg->PicOutputFlag) {
1852
0
    loginfo(LogDPB,"new picture has output-flag=true\n");
1853
1854
0
    if (outimg->integrity != INTEGRITY_CORRECT &&
1855
0
        param_suppress_faulty_pictures) {
1856
0
    }
1857
0
    else {
1858
0
      dpb.insert_image_into_reorder_buffer(outimg);
1859
0
    }
1860
1861
0
    loginfo(LogDPB,"push image %d into reordering queue\n", outimg->PicOrderCntVal);
1862
0
  }
1863
1864
  // check for full reorder buffers
1865
1866
0
  int maxNumPicsInReorderBuffer = 0;
1867
1868
  // TODO: I'd like to have the has_vps() check somewhere else (not decode the picture at all)
1869
0
  if (outimg->has_vps()) {
1870
0
    int sublayer = outimg->get_vps().vps_max_sub_layers -1;
1871
0
    maxNumPicsInReorderBuffer = outimg->get_vps().layer[sublayer].vps_max_num_reorder_pics;
1872
0
  }
1873
1874
0
  if (dpb.num_pictures_in_reorder_buffer() > maxNumPicsInReorderBuffer) {
1875
0
    dpb.output_next_picture_in_reorder_buffer();
1876
0
  }
1877
1878
0
  dpb.log_dpb_queues();
1879
1880
0
  return DE265_OK;
1881
0
}
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
0
{
1890
0
  *err = DE265_OK;
1891
1892
0
  flush_reorder_buffer_at_this_frame = false;
1893
1894
1895
  // get PPS and SPS for this slice
1896
1897
0
  int pps_id = hdr->slice_pic_parameter_set_id;
1898
0
  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
0
  current_pps = pps[pps_id];
1905
0
  current_sps = sps[ (int)current_pps->seq_parameter_set_id ];
1906
0
  current_vps = vps[ (int)current_sps->video_parameter_set_id ];
1907
1908
0
  calc_tid_and_framerate_ratio();
1909
1910
1911
  // --- prepare decoding of new picture ---
1912
1913
0
  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
0
    current_image_poc_lsb = hdr->slice_pic_order_cnt_lsb;
1920
1921
1922
0
    seq_parameter_set* sps = current_sps.get();
1923
1924
1925
    // --- find and allocate image buffer for decoding ---
1926
1927
0
    int image_buffer_idx;
1928
0
    bool isOutputImage = (!sps->sample_adaptive_offset_enabled_flag || param_disable_sao);
1929
0
    image_buffer_idx = dpb.new_image(current_sps, this, pts, user_data, isOutputImage);
1930
0
    if (image_buffer_idx < 0) {
1931
0
      *err = (de265_error)(-image_buffer_idx);
1932
0
      return false;
1933
0
    }
1934
1935
0
    /*de265_image* */ img = dpb.get_image(image_buffer_idx);
1936
0
    img->nal_hdr = *nal_hdr;
1937
1938
    // Note: sps is already set in new_image() -> ??? still the case with shared_ptr ?
1939
1940
0
    img->set_headers(current_vps, current_sps, current_pps);
1941
1942
0
    img->decctx = this;
1943
1944
0
    img->clear_metadata();
1945
1946
1947
0
    if (isIRAP(nal_unit_type)) {
1948
0
      if (isIDR(nal_unit_type) ||
1949
0
          isBLA(nal_unit_type) ||
1950
0
          first_decoded_picture ||
1951
0
          FirstAfterEndOfSequenceNAL)
1952
0
        {
1953
0
          NoRaslOutputFlag = true;
1954
0
          FirstAfterEndOfSequenceNAL = false;
1955
0
        }
1956
0
      else if (0) // TODO: set HandleCraAsBlaFlag by external means
1957
0
        {
1958
0
        }
1959
0
      else
1960
0
        {
1961
0
          NoRaslOutputFlag   = false;
1962
0
          HandleCraAsBlaFlag = false;
1963
0
        }
1964
0
    }
1965
1966
1967
0
    if (isRASL(nal_unit_type) &&
1968
0
        NoRaslOutputFlag)
1969
0
      {
1970
0
        img->PicOutputFlag = false;
1971
0
      }
1972
0
    else
1973
0
      {
1974
0
        img->PicOutputFlag = !!hdr->pic_output_flag;
1975
0
      }
1976
1977
0
    process_picture_order_count(hdr);
1978
1979
0
    if (hdr->first_slice_segment_in_pic_flag) {
1980
      // mark picture so that it is not overwritten by unavailable reference frames
1981
0
      img->PicState = UsedForShortTermReference;
1982
1983
0
      *err = process_reference_picture_set(hdr);
1984
0
      if (*err != DE265_OK) {
1985
0
        return false;
1986
0
      }
1987
0
    }
1988
1989
0
    img->PicState = UsedForShortTermReference;
1990
1991
0
    log_set_current_POC(img->PicOrderCntVal);
1992
1993
1994
    // next image is not the first anymore
1995
1996
0
    first_decoded_picture = false;
1997
0
  }
1998
0
  else {
1999
    // claims to be not the first slice, but there is no active image available
2000
2001
0
    if (img == nullptr) {
2002
0
      return false;
2003
0
    }
2004
0
  }
2005
2006
0
  if (hdr->slice_type == SLICE_TYPE_B ||
2007
0
      hdr->slice_type == SLICE_TYPE_P)
2008
0
    {
2009
0
      bool success = construct_reference_picture_lists(hdr);
2010
0
      if (!success) {
2011
0
        return false;
2012
0
      }
2013
0
    }
2014
2015
  //printf("process slice segment header\n");
2016
2017
0
  loginfo(LogHeaders,"end of process-slice-header\n");
2018
0
  dpb.log_dpb_content();
2019
2020
2021
0
  if (hdr->dependent_slice_segment_flag==0) {
2022
0
    hdr->SliceAddrRS = hdr->slice_segment_address;
2023
0
  } else {
2024
0
    hdr->SliceAddrRS = previous_slice_header->SliceAddrRS;
2025
0
  }
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
0
  loginfo(LogHeaders,"SliceAddrRS = %d\n",hdr->SliceAddrRS);
2033
2034
0
  return true;
2035
0
}
2036
2037
2038
void decoder_context::remove_images_from_dpb(const std::vector<int>& removeImageList)
2039
0
{
2040
0
  for (size_t i=0;i<removeImageList.size();i++) {
2041
0
    int idx = dpb.DPB_index_of_picture_with_ID( removeImageList[i] );
2042
0
    if (idx>=0) {
2043
      //printf("remove ID %d\n", removeImageList[i]);
2044
0
      de265_image* dpbimg = dpb.get_image( idx );
2045
0
      dpbimg->PicState = UnusedForReference;
2046
0
    }
2047
0
  }
2048
0
}
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
0
{
2062
0
  if (current_sps) { return current_sps->sps_max_sub_layers-1; }
2063
0
  if (current_vps) { return current_vps->vps_max_sub_layers-1; }
2064
2065
0
  return 6;
2066
0
}
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
0
{
2101
0
  int highestTID = get_highest_TID();
2102
2103
0
  for (int tid=highestTID ; tid>=0 ; tid--) {
2104
0
    int lower  = 100 *  tid   /(highestTID+1);
2105
0
    int higher = 100 * (tid+1)/(highestTID+1);
2106
2107
0
    for (int l=lower; l<=higher; l++) {
2108
0
      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
0
      if (tid > limit_HighestTid) {
2112
0
        tid   = limit_HighestTid;
2113
0
        ratio = 100;
2114
0
      }
2115
2116
0
      framedrop_tab[l].tid   = tid;
2117
0
      framedrop_tab[l].ratio = ratio;
2118
0
    }
2119
2120
0
    framedrop_tid_index[tid] = higher;
2121
0
  }
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
0
}
2133
2134
void decoder_context::calc_tid_and_framerate_ratio()
2135
0
{
2136
0
  int highestTID = get_highest_TID();
2137
2138
2139
  // if number of temporal layers changed, we have to recompute the framedrop table
2140
2141
0
  if (framedrop_tab[100].tid != highestTID) {
2142
0
    compute_framedrop_table();
2143
0
  }
2144
2145
0
  goal_HighestTid       = framedrop_tab[framerate_ratio].tid;
2146
0
  layer_framerate_ratio = framedrop_tab[framerate_ratio].ratio;
2147
2148
  // TODO: for now, we switch immediately
2149
0
  current_HighestTid = goal_HighestTid;
2150
0
}
2151
2152
2153
void error_queue::add_warning(de265_error warning, bool once)
2154
0
{
2155
0
  std::lock_guard<std::mutex> lock(m_mutex);
2156
2157
  // check if warning was already shown
2158
0
  if (once) {
2159
0
    if (std::find(warnings_shown.begin(), warnings_shown.end(), warning) != warnings_shown.end()) {
2160
0
      return;
2161
0
    }
2162
0
    warnings_shown.push_back(warning);
2163
0
  }
2164
2165
  // add warning to output queue
2166
0
  if (warnings.size() >= MAX_WARNINGS) {
2167
0
    warnings.back() = DE265_WARNING_WARNING_BUFFER_FULL;
2168
0
    return;
2169
0
  }
2170
2171
0
  warnings.push_back(warning);
2172
0
}
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
}