Coverage Report

Created: 2026-09-14 06:44

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