Coverage Report

Created: 2026-06-10 06:58

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/libde265/libde265/pps.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 "pps.h"
22
#include "decctx.h"
23
#include "util.h"
24
25
#include <assert.h>
26
#include <stdlib.h>
27
#include <string.h>
28
#include <mutex>
29
#include <memory>
30
#include <atomic>
31
#if defined(_MSC_VER) || defined(__MINGW32__)
32
# include <malloc.h>
33
#elif defined(HAVE_ALLOCA_H)
34
# include <alloca.h>
35
#endif
36
37
38
void pps_range_extension::reset()
39
324
{
40
324
  log2_max_transform_skip_block_size = 2;
41
324
  cross_component_prediction_enabled_flag = false;
42
324
  chroma_qp_offset_list_enabled_flag = false;
43
324
  diff_cu_chroma_qp_offset_depth = 0;
44
324
  chroma_qp_offset_list_len = 0;
45
324
  log2_sao_offset_scale_luma = 0;
46
324
  log2_sao_offset_scale_chroma = 0;
47
324
}
48
49
50
bool pps_range_extension::read(bitreader* br, decoder_context* ctx, const pic_parameter_set* pps)
51
0
{
52
0
  const seq_parameter_set* sps = ctx->get_sps(pps->seq_parameter_set_id);
53
54
0
  uint32_t uvlc;
55
56
0
  if (pps->transform_skip_enabled_flag) {
57
0
    uvlc = br->get_uvlc();
58
0
    if (uvlc == UVLC_ERROR ||
59
0
        uvlc > static_cast<uint32_t>(sps->Log2MaxTrafoSize) - 2) {
60
0
      ctx->add_warning(DE265_WARNING_PPS_HEADER_INVALID, false);
61
0
      return false;
62
0
    }
63
64
0
    log2_max_transform_skip_block_size = uvlc+2;
65
0
  }
66
67
0
  cross_component_prediction_enabled_flag = br->get_bits(1);
68
  // shall be 0 when ChromaArrayType is not 3 (Sec. 7.4.3.3.2)
69
0
  if (sps->ChromaArrayType != CHROMA_444 &&
70
0
      cross_component_prediction_enabled_flag) {
71
0
      ctx->add_warning(DE265_WARNING_PPS_HEADER_INVALID, false);
72
0
      return false;
73
0
  }
74
75
0
  chroma_qp_offset_list_enabled_flag = br->get_bits(1);
76
  // shall be 0 when ChromaArrayType is 0 (mono) (Sec. 7.4.3.3.2)
77
0
  if (sps->ChromaArrayType == CHROMA_MONO &&
78
0
      chroma_qp_offset_list_enabled_flag) {
79
0
      ctx->add_warning(DE265_WARNING_PPS_HEADER_INVALID, false);
80
0
      return false;
81
0
  }
82
83
0
  if (chroma_qp_offset_list_enabled_flag) {
84
0
    uvlc = br->get_uvlc();
85
0
    if (uvlc == UVLC_ERROR ||
86
0
        uvlc > static_cast<uint32_t>(sps->log2_diff_max_min_luma_coding_block_size)) {
87
0
      ctx->add_warning(DE265_WARNING_PPS_HEADER_INVALID, false);
88
0
      return false;
89
0
    }
90
91
0
    diff_cu_chroma_qp_offset_depth = uvlc;
92
93
94
0
    uvlc = br->get_uvlc();
95
0
    if (uvlc == UVLC_ERROR ||
96
0
        uvlc > 5) {
97
0
      ctx->add_warning(DE265_WARNING_PPS_HEADER_INVALID, false);
98
0
      return false;
99
0
    }
100
101
0
    chroma_qp_offset_list_len = uvlc+1;
102
103
0
    for (int i=0;i<chroma_qp_offset_list_len;i++) {
104
0
      int32_t svlc;
105
0
      svlc = br->get_svlc();
106
0
      if (svlc == SVLC_ERROR ||
107
0
          svlc < -12 || svlc > 12) {
108
0
        ctx->add_warning(DE265_WARNING_PPS_HEADER_INVALID, false);
109
0
        return false;
110
0
      }
111
112
0
      cb_qp_offset_list[i] = svlc;
113
114
0
      svlc = br->get_svlc();
115
0
      if (svlc == SVLC_ERROR ||
116
0
          svlc < -12 || svlc > 12) {
117
0
        ctx->add_warning(DE265_WARNING_PPS_HEADER_INVALID, false);
118
0
        return false;
119
0
      }
120
121
0
      cr_qp_offset_list[i] = svlc;
122
0
    }
123
0
  }
124
125
126
0
  uvlc = br->get_uvlc();
127
0
  if (uvlc == UVLC_ERROR ||
128
0
      uvlc > static_cast<uint32_t>(std::max(0, sps->BitDepth_Y-10))) {
129
0
    ctx->add_warning(DE265_WARNING_PPS_HEADER_INVALID, false);
130
0
    return false;
131
0
  }
132
133
0
  log2_sao_offset_scale_luma = uvlc;
134
135
0
  uvlc = br->get_uvlc();
136
0
  if (uvlc == UVLC_ERROR ||
137
0
      uvlc > static_cast<uint32_t>(std::max(0, sps->BitDepth_C-10))) {
138
0
    ctx->add_warning(DE265_WARNING_PPS_HEADER_INVALID, false);
139
0
    return false;
140
0
  }
141
142
0
  log2_sao_offset_scale_chroma = uvlc;
143
144
0
  return true;
145
0
}
146
147
148
void pps_range_extension::dump(int fd) const
149
0
{
150
0
  FILE* fh;
151
0
  if (fd==1) fh=stdout;
152
0
  else if (fd==2) fh=stderr;
153
0
  else { return; }
154
155
0
#define LOG0(t) log2fh(fh, t)
156
0
#define LOG1(t,d) log2fh(fh, t,d)
157
0
#define LOG2(t,d,e) log2fh(fh, t,d,e)
158
159
0
  LOG0("---------- PPS range-extension ----------\n");
160
0
  LOG1("log2_max_transform_skip_block_size      : %d\n", log2_max_transform_skip_block_size);
161
0
  LOG1("cross_component_prediction_enabled_flag : %d\n", cross_component_prediction_enabled_flag);
162
0
  LOG1("chroma_qp_offset_list_enabled_flag      : %d\n", chroma_qp_offset_list_enabled_flag);
163
0
  if (chroma_qp_offset_list_enabled_flag) {
164
0
    LOG1("diff_cu_chroma_qp_offset_depth          : %d\n", diff_cu_chroma_qp_offset_depth);
165
0
    LOG1("chroma_qp_offset_list_len               : %d\n", chroma_qp_offset_list_len);
166
0
    for (int i=0;i<chroma_qp_offset_list_len;i++) {
167
0
      LOG2("cb_qp_offset_list[%d]                    : %d\n", i,cb_qp_offset_list[i]);
168
0
      LOG2("cr_qp_offset_list[%d]                    : %d\n", i,cr_qp_offset_list[i]);
169
0
    }
170
0
  }
171
172
0
  LOG1("log2_sao_offset_scale_luma              : %d\n", log2_sao_offset_scale_luma);
173
0
  LOG1("log2_sao_offset_scale_chroma            : %d\n", log2_sao_offset_scale_chroma);
174
0
#undef LOG2
175
0
#undef LOG1
176
0
#undef LOG0
177
0
}
178
179
180
181
182
183
pic_parameter_set::pic_parameter_set()
184
108
{
185
108
  reset();
186
108
}
187
188
189
pic_parameter_set::~pic_parameter_set()
190
108
{
191
108
}
192
193
194
void pic_parameter_set::set_defaults(enum PresetSet)
195
216
{
196
216
  pps_read = false;
197
216
  sps = nullptr;
198
199
216
  pic_parameter_set_id = 0;
200
216
  seq_parameter_set_id = 0;
201
216
  dependent_slice_segments_enabled_flag = 0;
202
216
  sign_data_hiding_flag = 0;
203
216
  cabac_init_present_flag = 0;
204
216
  num_ref_idx_l0_default_active = 1;
205
216
  num_ref_idx_l1_default_active = 1;
206
207
216
  pic_init_qp = 27;
208
216
  constrained_intra_pred_flag = 0;
209
216
  transform_skip_enabled_flag = 0;
210
211
216
  cu_qp_delta_enabled_flag = 0;
212
216
  diff_cu_qp_delta_depth = 0;
213
214
216
  pic_cb_qp_offset = 0;
215
216
  pic_cr_qp_offset = 0;
216
216
  pps_slice_chroma_qp_offsets_present_flag = 0;
217
216
  weighted_pred_flag  = 0;
218
216
  weighted_bipred_flag= 0;
219
216
  output_flag_present_flag = 0;
220
216
  transquant_bypass_enable_flag = 0;
221
216
  entropy_coding_sync_enabled_flag = 0;
222
223
  // --- tiles ---
224
225
216
  tiles_enabled_flag = 0;
226
216
  num_tile_columns = 1;
227
216
  num_tile_rows    = 1;
228
216
  uniform_spacing_flag = 1;
229
230
231
  // --- ---
232
233
216
  loop_filter_across_tiles_enabled_flag = 1;
234
216
  pps_loop_filter_across_slices_enabled_flag = 1;
235
236
2.37k
  for (int i=0;i<DE265_MAX_TILE_COLUMNS;i++) { colWidth[i]=0; }
237
2.37k
  for (int i=0;i<DE265_MAX_TILE_ROWS;i++)    { rowHeight[i]=0; }
238
2.59k
  for (int i=0;i<=DE265_MAX_TILE_COLUMNS;i++) { colBd[i]=0; }
239
2.59k
  for (int i=0;i<=DE265_MAX_TILE_ROWS;i++)    { rowBd[i]=0; }
240
241
216
  scan.reset();
242
243
244
216
  Log2MinCuQpDeltaSize = 0;
245
246
216
  deblocking_filter_control_present_flag = 0;
247
216
  deblocking_filter_override_enabled_flag = 0;
248
216
  pic_disable_deblocking_filter_flag = 0;
249
250
216
  beta_offset = 0;
251
216
  tc_offset   = 0;
252
253
216
  pic_scaling_list_data_present_flag = 0;
254
  // TODO struct scaling_list_data scaling_list;
255
256
216
  lists_modification_present_flag = 0;
257
216
  log2_parallel_merge_level = 2;
258
259
216
  num_extra_slice_header_bits = 0;
260
216
  slice_segment_header_extension_present_flag = 0;
261
216
  pps_extension_flag = 0;
262
263
216
  pps_range_extension_flag = 0;
264
216
  pps_multilayer_extension_flag = 0;
265
216
  pps_extension_6bits = 0;
266
267
216
  range_extension.reset();
268
216
}
269
270
271
bool pic_parameter_set::read(bitreader* br, decoder_context* ctx)
272
108
{
273
108
  reset();
274
275
276
108
  uint32_t uvlc;
277
108
  uvlc = br->get_uvlc();
278
108
  if (uvlc == UVLC_ERROR || uvlc >= DE265_MAX_PPS_SETS) {
279
9
    ctx->add_warning(DE265_WARNING_NONEXISTING_PPS_REFERENCED, false);
280
9
    return false;
281
9
  }
282
99
  pic_parameter_set_id = uvlc;
283
284
99
  uvlc = br->get_uvlc();
285
99
  if (uvlc == UVLC_ERROR || uvlc >= DE265_MAX_SPS_SETS) {
286
12
    ctx->add_warning(DE265_WARNING_NONEXISTING_SPS_REFERENCED, false);
287
12
    return false;
288
12
  }
289
87
  seq_parameter_set_id = uvlc;
290
291
87
  dependent_slice_segments_enabled_flag = br->get_bits(1);
292
87
  output_flag_present_flag = br->get_bits(1);
293
87
  num_extra_slice_header_bits = br->get_bits(3);
294
87
  sign_data_hiding_flag = br->get_bits(1);
295
87
  cabac_init_present_flag = br->get_bits(1);
296
87
  uvlc = br->get_uvlc();
297
87
  if (uvlc == UVLC_ERROR || uvlc > 15) {
298
33
    ctx->add_warning(DE265_WARNING_PPS_HEADER_INVALID, false);
299
33
    return false;
300
33
  }
301
54
  num_ref_idx_l0_default_active = uvlc + 1;
302
303
54
  uvlc = br->get_uvlc();
304
54
  if (uvlc == UVLC_ERROR || uvlc > 15) {
305
12
    ctx->add_warning(DE265_WARNING_PPS_HEADER_INVALID, false);
306
12
    return false;
307
12
  }
308
42
  num_ref_idx_l1_default_active = uvlc + 1;
309
310
311
42
  if (!ctx->has_sps(seq_parameter_set_id)) {
312
42
    ctx->add_warning(DE265_WARNING_NONEXISTING_SPS_REFERENCED, false);
313
42
    return false;
314
42
  }
315
316
0
  sps = ctx->get_shared_sps(seq_parameter_set_id);
317
318
0
  {
319
0
    int32_t svlc;
320
    // init_qp_minus26 shall be in [-(26 + QpBdOffset_Y), +25] (Sec. 7.4.3.3.1)
321
0
    if ((svlc = br->get_svlc()) == SVLC_ERROR ||
322
0
        svlc < -(26 + sps->QpBdOffset_Y) || svlc > 25) {
323
0
      ctx->add_warning(DE265_WARNING_PPS_HEADER_INVALID, false);
324
0
      return false;
325
0
    }
326
0
    pic_init_qp = svlc + 26;
327
0
  }
328
329
0
  constrained_intra_pred_flag = br->get_bits(1);
330
0
  transform_skip_enabled_flag = br->get_bits(1);
331
0
  cu_qp_delta_enabled_flag = br->get_bits(1);
332
333
0
  if (cu_qp_delta_enabled_flag) {
334
    // diff_cu_qp_delta_depth shall be in [0, log2_diff_max_min_luma_coding_block_size] (Sec. 7.4.3.3.1)
335
0
    if ((uvlc = br->get_uvlc()) == UVLC_ERROR ||
336
0
        uvlc > sps->log2_diff_max_min_luma_coding_block_size) {
337
0
      ctx->add_warning(DE265_WARNING_PPS_HEADER_INVALID, false);
338
0
      return false;
339
0
    }
340
0
    diff_cu_qp_delta_depth = uvlc;
341
0
  } else {
342
0
    diff_cu_qp_delta_depth = 0;
343
0
  }
344
345
0
  {
346
0
    int32_t svlc;
347
0
    if ((svlc = br->get_svlc()) == SVLC_ERROR) {
348
0
      ctx->add_warning(DE265_WARNING_PPS_HEADER_INVALID, false);
349
0
      return false;
350
0
    }
351
0
    pic_cb_qp_offset = svlc;
352
0
  }
353
354
0
  {
355
0
    int32_t svlc;
356
0
    if ((svlc = br->get_svlc()) == SVLC_ERROR) {
357
0
      ctx->add_warning(DE265_WARNING_PPS_HEADER_INVALID, false);
358
0
      return false;
359
0
    }
360
0
    pic_cr_qp_offset = svlc;
361
0
  }
362
363
0
  pps_slice_chroma_qp_offsets_present_flag = br->get_bits(1);
364
0
  weighted_pred_flag = br->get_bits(1);
365
0
  weighted_bipred_flag = br->get_bits(1);
366
0
  transquant_bypass_enable_flag = br->get_bits(1);
367
0
  tiles_enabled_flag = br->get_bits(1);
368
0
  entropy_coding_sync_enabled_flag = br->get_bits(1);
369
370
371
  // --- tiles ---
372
373
0
  if (tiles_enabled_flag) {
374
0
    if ((uvlc = br->get_uvlc()) == UVLC_ERROR ||
375
0
        uvlc + 1 > DE265_MAX_TILE_COLUMNS ||
376
0
        uvlc + 1 > sps->PicWidthInCtbsY) {
377
0
      ctx->add_warning(DE265_WARNING_PPS_HEADER_INVALID, false);
378
0
      return false;
379
0
    }
380
0
    num_tile_columns = uvlc + 1;
381
382
0
    if ((uvlc = br->get_uvlc()) == UVLC_ERROR ||
383
0
        uvlc + 1 > DE265_MAX_TILE_ROWS ||
384
0
        uvlc + 1 > sps->PicHeightInCtbsY) {
385
0
      ctx->add_warning(DE265_WARNING_PPS_HEADER_INVALID, false);
386
0
      return false;
387
0
    }
388
0
    num_tile_rows = uvlc + 1;
389
390
0
    uniform_spacing_flag = br->get_bits(1);
391
392
0
    if (uniform_spacing_flag==false) {
393
0
      uint16_t lastColumnWidth = sps->PicWidthInCtbsY;
394
0
      uint16_t lastRowHeight   = sps->PicHeightInCtbsY;
395
396
0
      for (int i = 0; i < num_tile_columns - 1; i++) {
397
0
        if ((uvlc = br->get_uvlc()) == UVLC_ERROR ||
398
0
            uvlc + 1 >= lastColumnWidth) {
399
0
          ctx->add_warning(DE265_WARNING_PPS_HEADER_INVALID, false);
400
0
          return false;
401
0
        }
402
403
0
        colWidth[i] = uvlc + 1;
404
405
0
        lastColumnWidth -= colWidth[i];
406
0
      }
407
408
0
      colWidth[num_tile_columns - 1] = lastColumnWidth;
409
410
0
      for (int i = 0; i < num_tile_rows - 1; i++) {
411
0
        if ((uvlc = br->get_uvlc()) == UVLC_ERROR ||
412
0
            uvlc + 1 >= lastRowHeight) {
413
0
          ctx->add_warning(DE265_WARNING_PPS_HEADER_INVALID, false);
414
0
          return false;
415
0
        }
416
0
        rowHeight[i] = uvlc + 1;
417
0
        lastRowHeight -= rowHeight[i];
418
0
      }
419
420
421
0
      rowHeight[num_tile_rows-1] = lastRowHeight;
422
0
    }
423
424
0
    loop_filter_across_tiles_enabled_flag = br->get_bits(1);
425
426
0
  } else {
427
0
    num_tile_columns = 1;
428
0
    num_tile_rows    = 1;
429
0
    uniform_spacing_flag = 1;
430
0
    loop_filter_across_tiles_enabled_flag = 0;
431
0
  }
432
433
434
435
  // END tiles
436
437
438
439
0
  beta_offset = 0; // default value
440
0
  tc_offset   = 0; // default value
441
442
0
  pps_loop_filter_across_slices_enabled_flag = br->get_bits(1);
443
0
  deblocking_filter_control_present_flag = br->get_bits(1);
444
0
  if (deblocking_filter_control_present_flag) {
445
0
    deblocking_filter_override_enabled_flag = br->get_bits(1);
446
0
    pic_disable_deblocking_filter_flag = br->get_bits(1);
447
0
    if (!pic_disable_deblocking_filter_flag) {
448
0
      {
449
0
        int32_t svlc;
450
        // pps_beta_offset_div2 shall be in [-6, 6] (Sec. 7.4.3.3.1)
451
0
        if ((svlc = br->get_svlc()) == SVLC_ERROR || svlc < -6 || svlc > 6) {
452
0
    ctx->add_warning(DE265_WARNING_PPS_HEADER_INVALID, false);
453
0
    return false;
454
0
        }
455
0
        beta_offset = svlc * 2;
456
457
        // pps_tc_offset_div2 shall be in [-6, 6] (Sec. 7.4.3.3.1)
458
0
        if ((svlc = br->get_svlc()) == SVLC_ERROR || svlc < -6 || svlc > 6) {
459
0
    ctx->add_warning(DE265_WARNING_PPS_HEADER_INVALID, false);
460
0
    return false;
461
0
        }
462
0
        tc_offset = svlc * 2;
463
0
      }
464
0
    }
465
0
  }
466
0
  else {
467
0
    deblocking_filter_override_enabled_flag = 0;
468
0
    pic_disable_deblocking_filter_flag = 0;
469
0
  }
470
471
472
  // --- scaling list ---
473
474
0
  pic_scaling_list_data_present_flag = br->get_bits(1);
475
476
  // check consistency: if scaling-lists are not enabled, pic_scalign_list_data_present_flag
477
  // must be FALSE
478
0
  if (sps->scaling_list_enable_flag==0 &&
479
0
      pic_scaling_list_data_present_flag != 0) {
480
0
    ctx->add_warning(DE265_WARNING_PPS_HEADER_INVALID, false);
481
0
    return false;
482
0
  }
483
484
0
  if (pic_scaling_list_data_present_flag) {
485
0
    de265_error err = read_scaling_list(br, sps.get(), &scaling_list, true);
486
0
    if (err != DE265_OK) {
487
0
      ctx->add_warning(err, false);
488
0
      return false;
489
0
    }
490
0
  }
491
0
  else {
492
0
    scaling_list = sps->scaling_list;
493
0
  }
494
495
496
497
498
0
  lists_modification_present_flag = br->get_bits(1);
499
0
  if ((uvlc = br->get_uvlc()) == UVLC_ERROR || uvlc > 4) {
500
0
    ctx->add_warning(DE265_WARNING_PPS_HEADER_INVALID, false);
501
0
    return false;
502
0
  }
503
0
  log2_parallel_merge_level = uvlc + 2;
504
505
0
  if (log2_parallel_merge_level-2 > sps->log2_min_luma_coding_block_size-3 +1 +
506
0
      sps->log2_diff_max_min_luma_coding_block_size) {
507
0
    return false;
508
0
  }
509
510
0
  slice_segment_header_extension_present_flag = br->get_bits(1);
511
0
  pps_extension_flag = br->get_bits(1);
512
513
0
  if (pps_extension_flag) {
514
0
    pps_range_extension_flag = br->get_bits(1);
515
0
    pps_multilayer_extension_flag = br->get_bits(1);
516
0
    pps_extension_6bits = br->get_bits(6);
517
518
0
    if (pps_range_extension_flag) {
519
0
      bool success = range_extension.read(br, ctx, this);
520
0
      if (!success) {
521
0
        return false;
522
0
      }
523
0
    }
524
525
    // Multilayer extension and the 6 reserved extension bits would carry
526
    // additional payload that we do not parse. Reject the stream.
527
0
    if (pps_multilayer_extension_flag || pps_extension_6bits) {
528
0
      ctx->add_warning(DE265_ERROR_NOT_IMPLEMENTED_YET, false);
529
0
      return false;
530
0
    }
531
0
  }
532
533
534
0
  set_derived_values(sps.get());
535
536
0
  pps_read = true;
537
538
0
  return true;
539
0
}
540
541
542
//----------------------------------------------------------------------------
543
// Library-scope cache for the geometry-derived scan tables (HEVC Sec. 6.5).
544
//
545
// The tables depend only on the picture/tile geometry. Many independent decoder
546
// contexts (e.g. libheif tile grids) decode images of the same geometry, so we
547
// compute the tables once and share them read-only via shared_ptr. A small LRU
548
// cache (a few distinct geometries) protected by a mutex serves concurrent
549
// decoders. The compute is done while holding the lock on purpose: a burst of
550
// contexts with the same new geometry then computes the tables exactly once
551
// (the others block briefly and pick up the cached result).
552
//----------------------------------------------------------------------------
553
554
namespace {
555
556
struct pps_scan_key {
557
  uint8_t  log2CtbSize;
558
  uint8_t  log2MinTrafo;
559
  uint16_t picWidthInCtbs, picHeightInCtbs;
560
  uint16_t picWidthInTbs,  picHeightInTbs;
561
  uint32_t picSizeInCtbs,  picSizeInTbs;
562
  uint16_t numTileCols,    numTileRows;
563
  uint16_t colBd[DE265_MAX_TILE_COLUMNS+1];
564
  uint16_t rowBd[DE265_MAX_TILE_ROWS+1];
565
566
0
  bool operator==(const pps_scan_key& o) const {
567
0
    if (log2CtbSize    != o.log2CtbSize    || log2MinTrafo   != o.log2MinTrafo   ||
568
0
        picWidthInCtbs != o.picWidthInCtbs || picHeightInCtbs!= o.picHeightInCtbs||
569
0
        picWidthInTbs  != o.picWidthInTbs  || picHeightInTbs != o.picHeightInTbs ||
570
0
        picSizeInCtbs  != o.picSizeInCtbs  || picSizeInTbs   != o.picSizeInTbs   ||
571
0
        numTileCols    != o.numTileCols    || numTileRows    != o.numTileRows) return false;
572
0
    for (int i=0;i<=numTileCols;i++) if (colBd[i]!=o.colBd[i]) return false;
573
0
    for (int i=0;i<=numTileRows;i++) if (rowBd[i]!=o.rowBd[i]) return false;
574
0
    return true;
575
0
  }
576
};
577
578
// Build the five scan tables from the geometry key (HEVC 6.5.1 + 6.5.2).
579
std::shared_ptr<const pps_scan_tables> compute_scan_tables(const pps_scan_key& k)
580
0
{
581
0
  std::shared_ptr<pps_scan_tables> t = std::make_shared<pps_scan_tables>();
582
0
  t->CtbAddrRStoTS.resize(k.picSizeInCtbs);
583
0
  t->CtbAddrTStoRS.resize(k.picSizeInCtbs);
584
0
  t->TileId       .resize(k.picSizeInCtbs);
585
0
  t->TileIdRS     .resize(k.picSizeInCtbs);
586
0
  t->MinTbAddrZS  .resize(k.picSizeInTbs);
587
588
  // 6.5.1 raster (RS) <-> tile scan (TS) conversion + tile-ID assignment.
589
0
  uint32_t ctbAddrTS = 0;
590
0
  uint32_t tIdx = 0;
591
0
  for (int tileY=0; tileY<k.numTileRows; tileY++) {
592
0
    for (int tileX=0; tileX<k.numTileCols; tileX++) {
593
0
      for (int y=k.rowBd[tileY]; y<k.rowBd[tileY+1]; y++) {
594
0
        for (int x=k.colBd[tileX]; x<k.colBd[tileX+1]; x++) {
595
0
          uint32_t ctbAddrRS = y * k.picWidthInCtbs + x;
596
0
          t->CtbAddrRStoTS[ctbAddrRS] = ctbAddrTS;
597
0
          t->CtbAddrTStoRS[ctbAddrTS] = ctbAddrRS;
598
0
          t->TileId  [ctbAddrTS] = tIdx;
599
0
          t->TileIdRS[ctbAddrRS] = tIdx;
600
0
          ctbAddrTS++;
601
0
        }
602
0
      }
603
0
      tIdx++;
604
0
    }
605
0
  }
606
0
  assert(ctbAddrTS == k.picSizeInCtbs);
607
608
  // 6.5.2 Z-scan order array initialization process.
609
0
  const int shift = k.log2CtbSize - k.log2MinTrafo;
610
0
  for (int y=0; y<k.picHeightInTbs; y++)
611
0
    for (int x=0; x<k.picWidthInTbs; x++) {
612
0
      int tbX = (x<<k.log2MinTrafo)>>k.log2CtbSize;
613
0
      int tbY = (y<<k.log2MinTrafo)>>k.log2CtbSize;
614
0
      int ctbAddrRS = k.picWidthInCtbs*tbY + tbX;
615
616
0
      uint32_t v = t->CtbAddrRStoTS[ctbAddrRS] << (shift*2);
617
0
      int p=0;
618
0
      for (int i=0;i<shift;i++) {
619
0
        int m=1<<i;
620
0
        p += (m & x ? m*m : 0) + (m & y ? 2*m*m : 0);
621
0
      }
622
0
      t->MinTbAddrZS[x + y*k.picWidthInTbs] = v + p;
623
0
    }
624
625
0
  return t;
626
0
}
627
628
class pps_scan_cache {
629
public:
630
0
  std::shared_ptr<const pps_scan_tables> get(const pps_scan_key& key) {
631
0
    std::lock_guard<std::mutex> lock(mMutex);
632
633
0
    for (size_t i=0; i<mEntries.size(); i++) {
634
0
      if (mEntries[i].key == key) {
635
0
        std::shared_ptr<const pps_scan_tables> tables = mEntries[i].tables;
636
0
        if (i != 0) {  // move-to-front (LRU)
637
0
          Entry e = mEntries[i];
638
0
          mEntries.erase(mEntries.begin()+i);
639
0
          mEntries.insert(mEntries.begin(), e);
640
0
        }
641
0
        return tables;
642
0
      }
643
0
    }
644
645
    // Miss: compute while holding the lock so that a burst of concurrent decoders
646
    // with the same new geometry computes the tables exactly once.
647
0
    std::shared_ptr<const pps_scan_tables> tables = compute_scan_tables(key);
648
0
    mEntries.insert(mEntries.begin(), Entry{key, tables});
649
0
    if (mEntries.size() > kMaxEntries) mEntries.pop_back();  // evict LRU
650
0
    return tables;
651
0
  }
652
653
private:
654
  static const size_t kMaxEntries = 3;
655
  struct Entry { pps_scan_key key; std::shared_ptr<const pps_scan_tables> tables; };
656
  std::mutex mMutex;
657
  std::vector<Entry> mEntries;
658
};
659
660
// Owned by the de265_init()/de265_free() lifecycle (see de265.cc). It is created
661
// and destroyed (under de265's init mutex) while no decoder is running, so it is
662
// read locklessly during decoding; the cache's own mutex guards concurrent get()
663
// calls. Atomic so the publish/read of the pointer is well-defined.
664
std::atomic<pps_scan_cache*> g_pps_scan_cache{nullptr};
665
666
std::shared_ptr<const pps_scan_tables> get_pps_scan_tables(const pps_scan_key& key)
667
0
{
668
0
  pps_scan_cache* cache = g_pps_scan_cache.load(std::memory_order_acquire);
669
0
  if (cache) return cache->get(key);
670
0
  return compute_scan_tables(key);  // library not initialized: compute without caching
671
0
}
672
673
} // namespace
674
675
676
void pps_scan_cache_init()
677
2
{
678
2
  if (!g_pps_scan_cache.load(std::memory_order_relaxed)) {
679
2
    g_pps_scan_cache.store(new pps_scan_cache(), std::memory_order_release);
680
2
  }
681
2
}
682
683
void pps_scan_cache_free()
684
0
{
685
0
  delete g_pps_scan_cache.exchange(nullptr, std::memory_order_acq_rel);
686
0
}
687
688
689
void pic_parameter_set::set_derived_values(const seq_parameter_set* sps)
690
0
{
691
0
  Log2MinCuQpDeltaSize = sps->Log2CtbSizeY - diff_cu_qp_delta_depth;
692
693
0
  Log2MinCuChromaQpOffsetSize = sps->Log2CtbSizeY - range_extension.diff_cu_chroma_qp_offset_depth;
694
0
  Log2MaxTransformSkipSize = range_extension.log2_max_transform_skip_block_size;
695
696
0
  if (uniform_spacing_flag) {
697
698
    // set columns widths
699
700
0
    int *const colPos = static_cast<int*>(alloca((num_tile_columns+1) * sizeof(int)));
701
702
0
    for (int i=0;i<=num_tile_columns;i++) {
703
0
      colPos[i] = i*sps->PicWidthInCtbsY / num_tile_columns;
704
0
    }
705
0
    for (int i=0;i<num_tile_columns;i++) {
706
0
      colWidth[i] = colPos[i+1] - colPos[i];
707
0
    }
708
709
    // set row heights
710
711
0
    int *const rowPos = static_cast<int*>(alloca((num_tile_rows+1) * sizeof(int)));
712
713
0
    for (int i=0;i<=num_tile_rows;i++) {
714
0
      rowPos[i] = i*sps->PicHeightInCtbsY / num_tile_rows;
715
0
    }
716
0
    for (int i=0;i<num_tile_rows;i++) {
717
0
      rowHeight[i] = rowPos[i+1] - rowPos[i];
718
0
    }
719
0
  }
720
721
722
  // set tile boundaries
723
724
0
  colBd[0]=0;
725
0
  for (int i=0;i<num_tile_columns;i++) {
726
0
    colBd[i+1] = colBd[i] + colWidth[i];
727
0
  }
728
729
0
  rowBd[0]=0;
730
0
  for (int i=0;i<num_tile_rows;i++) {
731
0
    rowBd[i+1] = rowBd[i] + rowHeight[i];
732
0
  }
733
734
735
736
  // The derived scan tables (Sec. 6.5.1 + 6.5.2) depend only on the picture/tile
737
  // geometry computed above. Build the geometry key and fetch the shared tables
738
  // from the library-scope cache (computing+caching them on a miss). This avoids
739
  // recomputing the (potentially large) MinTbAddrZS table for every decoder
740
  // context when many contexts decode images of the same geometry.
741
742
0
  pps_scan_key key;
743
0
  memset(&key, 0, sizeof(key));   // zero padding/unused tile entries for clean compares
744
0
  key.log2CtbSize     = sps->Log2CtbSizeY;
745
0
  key.log2MinTrafo    = sps->Log2MinTrafoSize;
746
0
  key.picWidthInCtbs  = sps->PicWidthInCtbsY;
747
0
  key.picHeightInCtbs = sps->PicHeightInCtbsY;
748
0
  key.picWidthInTbs   = sps->PicWidthInTbsY;
749
0
  key.picHeightInTbs  = sps->PicHeightInTbsY;
750
0
  key.picSizeInCtbs   = sps->PicSizeInCtbsY;
751
0
  key.picSizeInTbs    = sps->PicSizeInTbsY;
752
0
  key.numTileCols     = num_tile_columns;
753
0
  key.numTileRows     = num_tile_rows;
754
0
  for (int i=0;i<=num_tile_columns;i++) key.colBd[i] = colBd[i];
755
0
  for (int i=0;i<=num_tile_rows;   i++) key.rowBd[i] = rowBd[i];
756
757
0
  scan = get_pps_scan_tables(key);
758
0
}
759
760
761
bool pic_parameter_set::write(error_queue* errqueue, CABAC_encoder& out,
762
                              const seq_parameter_set* sps)
763
0
{
764
0
  if (pic_parameter_set_id >= DE265_MAX_PPS_SETS) {
765
0
    errqueue->add_warning(DE265_WARNING_NONEXISTING_PPS_REFERENCED, false);
766
0
    return false;
767
0
  }
768
0
  out.write_uvlc(pic_parameter_set_id);
769
770
0
  if (seq_parameter_set_id >= DE265_MAX_SPS_SETS) {
771
0
    errqueue->add_warning(DE265_WARNING_NONEXISTING_SPS_REFERENCED, false);
772
0
    return false;
773
0
  }
774
0
  out.write_uvlc(seq_parameter_set_id);
775
776
0
  out.write_bit(dependent_slice_segments_enabled_flag);
777
0
  out.write_bit(output_flag_present_flag);
778
0
  out.write_bits(num_extra_slice_header_bits,3);
779
0
  out.write_bit(sign_data_hiding_flag);
780
0
  out.write_bit(cabac_init_present_flag);
781
0
  out.write_uvlc(num_ref_idx_l0_default_active-1);
782
0
  out.write_uvlc(num_ref_idx_l1_default_active-1);
783
784
0
  out.write_svlc(pic_init_qp-26);
785
786
0
  out.write_bit(constrained_intra_pred_flag);
787
0
  out.write_bit(transform_skip_enabled_flag);
788
0
  out.write_bit(cu_qp_delta_enabled_flag);
789
790
0
  if (cu_qp_delta_enabled_flag) {
791
0
    out.write_uvlc(diff_cu_qp_delta_depth);
792
0
  }
793
794
0
  out.write_svlc(pic_cb_qp_offset);
795
0
  out.write_svlc(pic_cr_qp_offset);
796
797
0
  out.write_bit(pps_slice_chroma_qp_offsets_present_flag);
798
0
  out.write_bit(weighted_pred_flag);
799
0
  out.write_bit(weighted_bipred_flag);
800
0
  out.write_bit(transquant_bypass_enable_flag);
801
0
  out.write_bit(tiles_enabled_flag);
802
0
  out.write_bit(entropy_coding_sync_enabled_flag);
803
804
805
  // --- tiles ---
806
807
0
  if (tiles_enabled_flag) {
808
0
    if (num_tile_columns > DE265_MAX_TILE_COLUMNS) {
809
0
      errqueue->add_warning(DE265_WARNING_PPS_HEADER_INVALID, false);
810
0
      return false;
811
0
    }
812
0
    out.write_uvlc(num_tile_columns-1);
813
814
0
    if (num_tile_rows > DE265_MAX_TILE_ROWS) {
815
0
      errqueue->add_warning(DE265_WARNING_PPS_HEADER_INVALID, false);
816
0
      return false;
817
0
    }
818
0
    out.write_uvlc(num_tile_rows-1);
819
820
0
    out.write_bit(uniform_spacing_flag);
821
822
0
    if (uniform_spacing_flag==false) {
823
0
      for (int i=0; i<num_tile_columns-1; i++)
824
0
        {
825
0
          out.write_uvlc(colWidth[i]-1);
826
0
        }
827
828
0
      for (int i=0; i<num_tile_rows-1; i++)
829
0
        {
830
0
          out.write_uvlc(rowHeight[i]-1);
831
0
        }
832
0
    }
833
834
0
    out.write_bit(loop_filter_across_tiles_enabled_flag);
835
0
  }
836
837
838
0
  out.write_bit(pps_loop_filter_across_slices_enabled_flag);
839
0
  out.write_bit(deblocking_filter_control_present_flag);
840
841
0
  if (deblocking_filter_control_present_flag) {
842
0
    out.write_bit(deblocking_filter_override_enabled_flag);
843
0
    out.write_bit(pic_disable_deblocking_filter_flag);
844
845
0
    if (!pic_disable_deblocking_filter_flag) {
846
0
      out.write_svlc(beta_offset/2);
847
0
      out.write_svlc(tc_offset  /2);
848
0
    }
849
0
  }
850
851
852
  // --- scaling list ---
853
854
0
  out.write_bit(pic_scaling_list_data_present_flag);
855
856
  // check consistency: if scaling-lists are not enabled, pic_scalign_list_data_present_flag
857
  // must be FALSE
858
0
  if (sps->scaling_list_enable_flag==0 &&
859
0
      pic_scaling_list_data_present_flag != 0) {
860
0
    errqueue->add_warning(DE265_WARNING_PPS_HEADER_INVALID, false);
861
0
    return false;
862
0
  }
863
864
0
  if (pic_scaling_list_data_present_flag) {
865
0
    de265_error err = write_scaling_list(out, sps, &scaling_list, true);
866
0
    if (err != DE265_OK) {
867
0
      errqueue->add_warning(err, false);
868
0
      return false;
869
0
    }
870
0
  }
871
872
873
874
0
  out.write_bit(lists_modification_present_flag);
875
0
  out.write_uvlc(log2_parallel_merge_level-2);
876
877
0
  out.write_bit(slice_segment_header_extension_present_flag);
878
0
  out.write_bit(pps_extension_flag);
879
880
0
  if (pps_extension_flag) {
881
    //assert(false);
882
    /*
883
      while( more_rbsp_data() )
884
885
      pps_extension_data_flag
886
      u(1)
887
      rbsp_trailing_bits()
888
889
      }
890
    */
891
0
  }
892
893
894
0
  pps_read = true;
895
896
0
  return true;
897
0
}
898
899
900
void pic_parameter_set::dump(int fd) const
901
0
{
902
0
  FILE* fh;
903
0
  if (fd==1) fh=stdout;
904
0
  else if (fd==2) fh=stderr;
905
0
  else { return; }
906
907
0
#define LOG0(t) log2fh(fh, t)
908
0
#define LOG1(t,d) log2fh(fh, t,d)
909
910
0
  LOG0("----------------- PPS -----------------\n");
911
0
  LOG1("pic_parameter_set_id       : %d\n", pic_parameter_set_id);
912
0
  LOG1("seq_parameter_set_id       : %d\n", seq_parameter_set_id);
913
0
  LOG1("dependent_slice_segments_enabled_flag : %d\n", dependent_slice_segments_enabled_flag);
914
0
  LOG1("sign_data_hiding_flag      : %d\n", sign_data_hiding_flag);
915
0
  LOG1("cabac_init_present_flag    : %d\n", cabac_init_present_flag);
916
0
  LOG1("num_ref_idx_l0_default_active : %d\n", num_ref_idx_l0_default_active);
917
0
  LOG1("num_ref_idx_l1_default_active : %d\n", num_ref_idx_l1_default_active);
918
919
0
  LOG1("pic_init_qp                : %d\n", pic_init_qp);
920
0
  LOG1("constrained_intra_pred_flag: %d\n", constrained_intra_pred_flag);
921
0
  LOG1("transform_skip_enabled_flag: %d\n", transform_skip_enabled_flag);
922
0
  LOG1("cu_qp_delta_enabled_flag   : %d\n", cu_qp_delta_enabled_flag);
923
924
0
  if (cu_qp_delta_enabled_flag) {
925
0
    LOG1("diff_cu_qp_delta_depth     : %d\n", diff_cu_qp_delta_depth);
926
0
  }
927
928
0
  LOG1("pic_cb_qp_offset             : %d\n", pic_cb_qp_offset);
929
0
  LOG1("pic_cr_qp_offset             : %d\n", pic_cr_qp_offset);
930
0
  LOG1("pps_slice_chroma_qp_offsets_present_flag : %d\n", pps_slice_chroma_qp_offsets_present_flag);
931
0
  LOG1("weighted_pred_flag           : %d\n", weighted_pred_flag);
932
0
  LOG1("weighted_bipred_flag         : %d\n", weighted_bipred_flag);
933
0
  LOG1("output_flag_present_flag     : %d\n", output_flag_present_flag);
934
0
  LOG1("transquant_bypass_enable_flag: %d\n", transquant_bypass_enable_flag);
935
0
  LOG1("tiles_enabled_flag           : %d\n", tiles_enabled_flag);
936
0
  LOG1("entropy_coding_sync_enabled_flag: %d\n", entropy_coding_sync_enabled_flag);
937
938
0
  if (tiles_enabled_flag) {
939
0
    LOG1("num_tile_columns    : %d\n", num_tile_columns);
940
0
    LOG1("num_tile_rows       : %d\n", num_tile_rows);
941
0
    LOG1("uniform_spacing_flag: %d\n", uniform_spacing_flag);
942
943
0
    LOG0("tile column boundaries: ");
944
0
    for (int i=0;i<=num_tile_columns;i++) {
945
0
      LOG1("*%d ",colBd[i]);
946
0
    }
947
0
    LOG0("*\n");
948
949
0
    LOG0("tile row boundaries: ");
950
0
    for (int i=0;i<=num_tile_rows;i++) {
951
0
      LOG1("*%d ",rowBd[i]);
952
0
    }
953
0
    LOG0("*\n");
954
955
  //if( !uniform_spacing_flag ) {
956
  /*
957
            for( i = 0; i < num_tile_columns_minus1; i++ )
958
959
              column_width_minus1[i]
960
                ue(v)
961
                for( i = 0; i < num_tile_rows_minus1; i++ )
962
963
                  row_height_minus1[i]
964
                    ue(v)
965
                    }
966
  */
967
968
0
    LOG1("loop_filter_across_tiles_enabled_flag : %d\n", loop_filter_across_tiles_enabled_flag);
969
0
  }
970
971
0
  LOG1("pps_loop_filter_across_slices_enabled_flag: %d\n", pps_loop_filter_across_slices_enabled_flag);
972
0
  LOG1("deblocking_filter_control_present_flag: %d\n", deblocking_filter_control_present_flag);
973
974
0
  if (deblocking_filter_control_present_flag) {
975
0
    LOG1("deblocking_filter_override_enabled_flag: %d\n", deblocking_filter_override_enabled_flag);
976
0
    LOG1("pic_disable_deblocking_filter_flag: %d\n", pic_disable_deblocking_filter_flag);
977
978
0
    LOG1("beta_offset:  %d\n", beta_offset);
979
0
    LOG1("tc_offset:    %d\n", tc_offset);
980
0
  }
981
982
0
  LOG1("pic_scaling_list_data_present_flag: %d\n", pic_scaling_list_data_present_flag);
983
0
  if (pic_scaling_list_data_present_flag) {
984
    //scaling_list_data()
985
0
  }
986
987
0
  LOG1("lists_modification_present_flag: %d\n", lists_modification_present_flag);
988
0
  LOG1("log2_parallel_merge_level      : %d\n", log2_parallel_merge_level);
989
0
  LOG1("num_extra_slice_header_bits    : %d\n", num_extra_slice_header_bits);
990
0
  LOG1("slice_segment_header_extension_present_flag : %d\n", slice_segment_header_extension_present_flag);
991
0
  LOG1("pps_extension_flag            : %d\n", pps_extension_flag);
992
0
  LOG1("pps_range_extension_flag      : %d\n", pps_range_extension_flag);
993
0
  LOG1("pps_multilayer_extension_flag : %d\n", pps_multilayer_extension_flag);
994
0
  LOG1("pps_extension_6bits           : %d\n", pps_extension_6bits);
995
996
0
  LOG1("Log2MinCuQpDeltaSize          : %d\n", Log2MinCuQpDeltaSize);
997
0
  LOG1("Log2MinCuChromaQpOffsetSize (RExt) : %d\n", Log2MinCuChromaQpOffsetSize);
998
0
  LOG1("Log2MaxTransformSkipSize    (RExt) : %d\n", Log2MaxTransformSkipSize);
999
1000
0
#undef LOG0
1001
0
#undef LOG1
1002
1003
1004
0
  if (pps_range_extension_flag) {
1005
0
    range_extension.dump(fd);
1006
0
  }
1007
0
}
1008
1009
1010
bool pic_parameter_set::is_tile_start_CTB(int ctbX,int ctbY) const
1011
0
{
1012
  // fast check
1013
0
  if (tiles_enabled_flag==0) {
1014
0
    return ctbX == 0 && ctbY == 0;
1015
0
  }
1016
1017
0
  for (int i=0;i<num_tile_columns;i++)
1018
0
    if (colBd[i]==ctbX)
1019
0
      {
1020
0
        for (int k=0;k<num_tile_rows;k++)
1021
0
          if (rowBd[k]==ctbY)
1022
0
            {
1023
0
              return true;
1024
0
            }
1025
1026
0
        return false;
1027
0
      }
1028
1029
0
  return false;
1030
0
}