hls.h 11.9 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
/* The copyright in this software is being made available under the BSD
 * Licence, included below.  This software may be subject to other third
 * party and contributor rights, including patent rights, and no such
 * rights are granted under this licence.
 *
 * Copyright (c) 2017-2018, ISO/IEC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 *
 * * Neither the name of the ISO/IEC nor the names of its contributors
 *   may be used to endorse or promote products derived from this
 *   software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once

#include "PCCMath.h"

#include <cstdint>
#include <ostream>
#include <vector>

namespace pcc {

//============================================================================

enum class PayloadType
{
  kSequenceParameterSet = 0,
  kGeometryParameterSet = 1,
  kGeometryBrick = 2,
  kAttributeParameterSet = 3,
  kAttributeBrick = 4,
55
  kTileInventory = 5,
56
  kFrameBoundaryMarker = 6,
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
};

//============================================================================

enum class KnownAttributeLabel : uint32_t
{
  kColour = 0,
  kReflectance = 1,
};

//============================================================================

struct AttributeLabel {
  uint32_t attribute_label_four_bytes = 0xffffffffu;

  //--------------------------------------------------------------------------

  AttributeLabel() = default;

  AttributeLabel(KnownAttributeLabel known_attribute_label)
  {
    attribute_label_four_bytes = int(known_attribute_label);
  }

  //--------------------------------------------------------------------------

  friend bool
  operator==(const AttributeLabel& lhs, const KnownAttributeLabel& rhs)
  {
    return uint32_t(rhs) == lhs.attribute_label_four_bytes;
  }

  //--------------------------------------------------------------------------

91
92
93
94
95
96
97
98
  friend bool
  operator!=(const AttributeLabel& lhs, const KnownAttributeLabel& rhs)
  {
    return !(lhs == rhs);
  }

  //--------------------------------------------------------------------------

99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
  bool known_attribute_label_flag() const
  {
    switch (KnownAttributeLabel(attribute_label_four_bytes)) {
    case KnownAttributeLabel::kColour:
    case KnownAttributeLabel::kReflectance: return true;
    }

    return false;
  }

  //--------------------------------------------------------------------------

  KnownAttributeLabel known_attribute_label() const
  {
    return KnownAttributeLabel(attribute_label_four_bytes);
  }
};

//============================================================================

std::ostream& operator<<(std::ostream& os, const AttributeLabel& label);

//============================================================================

enum class AttributeEncoding
{
  kPredictingTransform = 0,
  kRAHTransform = 1,
  kLiftingTransform = 2,
};

//============================================================================

132
133
134
135
136
137
138
139
140
141
142
143
enum class AxisOrder
{
  kZYX = 0,
  kXYZ = 1,
  kXZY = 2,
  kYZX = 3,
  kZYX_4 = 4,
  kZXY = 5,
  kYXZ = 6,
  kXYZ_7 = 7,
};

144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
//============================================================================
// ISO/IEC 23001-8 codec independent code points
enum class ColourMatrix : uint8_t
{
  kIdentity = 0,
  kBt709 = 1,
  kUnspecified = 2,
  kReserved_3 = 3,
  kUsa47Cfr73dot682a20 = 4,
  kBt601 = 5,
  kSmpte170M = 6,
  kSmpte240M = 7,
  kYCgCo = 8,
  kBt2020Ncl = 9,
  kBt2020Cl = 10,
  kSmpte2085 = 11,
};

162
163
//============================================================================

164
165
// invariant properties
struct AttributeDescription {
166
  int attr_num_dimensions;
167
  int attr_instance_id;
168
  int attr_bitdepth;
169
  int attr_bitdepth_secondary;
170
171
  int cicp_colour_primaries_idx;
  int cicp_transfer_characteristics_idx;
172
  ColourMatrix cicp_matrix_coefficients_idx;
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
  bool cicp_video_full_range_flag;

  AttributeLabel attributeLabel;
};

//============================================================================

struct ProfileCompatibility {
  int profile_compatibility_flags;
};

//============================================================================

struct SequenceParameterSet {
  int sps_seq_parameter_set_id;

  ProfileCompatibility profileCompatibility;
  int level;

  // todo(df): encode the following
193
194
  Vec3<int> seq_bounding_box_xyz0;
  Vec3<int> seq_bounding_box_whd;
195
196
197
198
199
200
201
  //int seq_bounding_box_scale_log2;

  // A value describing the scaling of the source positions prior to encoding.
  float seq_source_geom_scale_factor;

  // NB: attributeSets.size() = num_attribute_sets
  std::vector<AttributeDescription> attributeSets;
202

203
204
205
  // The number of bits to use for frame_idx
  int log2_max_frame_idx;

206
207
208
  // Defines the ordering of the position components (eg, xyz vs zyx)
  AxisOrder geometry_axis_order;

209
210
211
  // Controls whether bypass bins are written to a seperate sub-stream, or
  // encoded as ep bins via CABAC.
  bool cabac_bypass_stream_enabled_flag;
212
213
214
215
216
217
218
219
220
221
222
223
};

//============================================================================

struct GeometryParameterSet {
  int gps_geom_parameter_set_id;
  int gps_seq_parameter_set_id;

  // Indicates that the GeometryBrickHeader contains a valid
  // geom_box_origin_xyz.
  int geom_box_present_flag;

224
225
226
227
228
229
230
  // Indicates the presence of gps_geom_box_log2_scale and
  // geom_box_log2_scale.
  bool geom_box_log2_scale_present_flag;

  // Default scaling factor for per-slice geometry box origin
  int gps_geom_box_log2_scale;

231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
  // Controls the ability to represent multiple points (with associated
  // attributes) at the same spatial position.
  bool geom_unique_points_flag;

  // Controls the use of neighbour based contextualisation of octree
  // occupancy during geometry coding.  When true, only neighbours that
  // are direct siblings are available.
  bool neighbour_context_restriction_flag;

  // Defines the size of the neighbour availiability volume (aka
  // look-ahead cube size) for occupancy searches.  A value of 0
  // indicates that the feature is disabled.
  int neighbour_avail_boundary_log2;

  // Controls the use of early termination of the geometry tree
  // by directly coding the position of isolated points.
  bool inferred_direct_coding_mode_enabled_flag;

249
250
  // Selects between bitwise and bytewise occupancy coding
  bool bitwise_occupancy_coding_flag;
251
252
253
254
255

  // Controlls contextualization of occupancy bits and refinement of
  // the neighbour pattern according to the occupancy of adjacent
  // children in neighbouring nodes.
  bool adjacent_child_contextualization_enabled_flag;
256

257
258
259
260
  // Experimental knob to control the number of contexts used
  // for occupancy coding.
  int geom_occupancy_ctx_reduction_factor;

261
262
263
  // Maximum node size where intra prediction is enabled
  int intra_pred_max_node_size_log2;

264
265
266
  // size of triangle nodes (reconstructed surface) in trisoup geometry.
  // a value of zero disables the feature
  int trisoup_node_size_log2;
267
268
269
270
271
272

  // controls the ability to perform in-loop geometry scaling
  bool geom_scaling_enabled_flag;

  // intial qp for geometry scaling
  int geom_base_qp;
273
274
275
276
277
278
279
280
281
282

  // Enables/disables non-cubic geometry nodes
  bool implicit_qtbt_enabled_flag;

  // maximum number of implicit qtbt before performing octree partition
  // for geometry coding.
  int max_num_implicit_qtbt_before_ot;

  // minimum size in log2 of implicit qtbt for geometry coding.
  int min_implicit_qtbt_size_log2;
283
284
285
286
287
288
289

  // Controls the use of planar mode
  bool geom_planar_mode_enabled_flag;
  int geom_planar_threshold0;
  int geom_planar_threshold1;
  int geom_planar_threshold2;
  int geom_planar_idcm_threshold;
290
291
292
293
294
295
};

//============================================================================

struct GeometryBrickHeader {
  int geom_geom_parameter_set_id;
296
  int geom_tile_id;
297
  int geom_slice_id;
298
  int frame_idx;
299
300

  // derived from geom_box_origin_{x,y,z} * (1 << geom_box_log2_scale)
301
  Vec3<int> geomBoxOrigin;
302
303
304
305
  int geom_box_log2_scale;

  // todo(df): minus1?
  int geom_max_node_size_log2;
306
  Vec3<int> geom_max_node_size_log2_xyz;
307
  int geom_num_points;
308

309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
  int geomMaxNodeSizeLog2(const GeometryParameterSet& gps) const
  {
    if (gps.implicit_qtbt_enabled_flag)
      return std::max({geom_max_node_size_log2_xyz[0],
                       geom_max_node_size_log2_xyz[1],
                       geom_max_node_size_log2_xyz[2]});
    return geom_max_node_size_log2;
  }

  Vec3<int> geomMaxNodeSizeLog2Xyz(const GeometryParameterSet& gps) const
  {
    if (gps.implicit_qtbt_enabled_flag)
      return geom_max_node_size_log2_xyz;
    return geom_max_node_size_log2;
  }

325
326
327
  // qp offset for geometry scaling (if enabled)
  int geom_slice_qp_offset;

328
329
330
331
332
333
  // enables signalling of qp offsets within the octree
  bool geom_octree_qp_offset_enabled_flag;

  // octree depth at which qp offsets whould be signalled
  int geom_octree_qp_offset_depth;

334
335
336
337
338
339
340
341
  int geomBoxLog2Scale(const GeometryParameterSet& gps) const
  {
    if (!gps.geom_box_present_flag)
      return 0;
    if (!gps.geom_box_log2_scale_present_flag)
      return gps.gps_geom_box_log2_scale;
    return geom_box_log2_scale;
  }
342
343
344
};

//============================================================================
345
// NB: when updating this, remember to update AttributeLods::isReusable(...)
346
347
348
349
350
351

struct AttributeParameterSet {
  int aps_attr_parameter_set_id;
  int aps_seq_parameter_set_id;
  AttributeEncoding attr_encoding;

352
  //--- lifting/predicting transform parameters
353

354
  bool lod_decimation_enabled_flag;
355
  int num_pred_nearest_neighbours;
356
  int max_num_direct_predictors;
357
  int adaptive_prediction_threshold;
358
  int search_range;
359
  Vec3<int32_t> lod_neigh_bias;
360
  bool intra_lod_prediction_enabled_flag;
361
  bool inter_component_prediction_enabled_flag;
362
363

  // NB: derived from num_detail_levels_minus1
364
  int num_detail_levels;
365
  std::vector<int64_t> dist2;
366

367
368
369
  // NB: these parameters are shared by all transform implementations
  int init_qp;
  int aps_chroma_qp_offset;
370
  bool aps_slice_qp_deltas_present_flag;
371
372

  //--- raht parameters
373
  bool raht_prediction_enabled_flag;
374
  int raht_depth;
375
376
377

  //--- lifting parameters
  bool scalable_lifting_enabled_flag;
378
379
380
381
382
};

//============================================================================

struct AttributeBrickHeader {
383
  int attr_sps_attr_idx;
384
  int attr_attr_parameter_set_id;
385
  int attr_geom_slice_id;
386
387
  int attr_qp_delta_luma;
  int attr_qp_delta_chroma;
388
389
390
391
392
393
394
395

  std::vector<int> attr_layer_qp_delta_luma;
  std::vector<int> attr_layer_qp_delta_chroma;

  bool attr_layer_qp_present_flag() const
  {
    return !attr_layer_qp_delta_luma.empty();
  }
396
397
398
399
400

  Vec3<int> attr_region_qp_origin;
  Vec3<int> attr_region_qp_whd;
  int attr_region_qp_delta;
  bool attr_region_qp_present_flag;
401
402
403
404
};

//============================================================================

405
406
struct TileInventory {
  struct Entry {
407
408
    Vec3<int> tile_bounding_box_xyz0;
    Vec3<int> tile_bounding_box_whd;
409
410
411
412
413
414
  };
  std::vector<Entry> tiles;
};

//============================================================================

415
}  // namespace pcc