Commit 23ba6f71 authored by Khaled Mammou's avatar Khaled Mammou Committed by David Flynn
Browse files

geom/m43592: use dual lut coder for bytewise occupancy coding

This commit allows bytewise encoding of occupancy symbols using the
dual-lut coder.
parent 7605654e
......@@ -304,6 +304,12 @@ ParseParameters(int argc, char* argv[], Parameters& params)
" 1: octree (TMC3)\n"
" 2: trisoup (TMC1)")
("bitwiseOccupancyCoding",
params.encoder.gps.bitwise_occupancy_coding_flag, true,
"Selects between bitwise and bytewise occupancy coding:\n"
" 0: bytewise\n"
" 1: bitwise")
("neighbourContextRestriction",
params.encoder.gps.neighbour_context_restriction_flag, false,
"Limit geometry octree occupancy contextualisation to sibling nodes")
......
......@@ -35,6 +35,7 @@
#include "geometry.h"
#include "DualLutCoder.h"
#include "OctreeNeighMap.h"
#include "geometry_octree.h"
#include "io_hls.h"
......@@ -46,7 +47,11 @@ namespace pcc {
class GeometryOctreeDecoder {
public:
GeometryOctreeDecoder(o3dgc::Arithmetic_Codec* arithmeticDecoder);
GeometryOctreeDecoder(
const GeometryParameterSet& gps,
o3dgc::Arithmetic_Codec* arithmeticDecoder);
void beginOctreeLevel();
int decodePositionLeafNumPoints();
......@@ -56,6 +61,8 @@ public:
int decodeOccupancyBitwise(int neighPattern);
int decodeOccupancyBytewise(int neighPattern);
uint32_t decodeOccupancy(int neighPattern);
PCCVector3<uint32_t> decodePointPosition(int nodeSizeLog2);
......@@ -75,15 +82,35 @@ private:
o3dgc::Adaptive_Bit_Model _ctxPointCountPerBlock;
o3dgc::Adaptive_Bit_Model _ctxBlockSkipTh;
o3dgc::Adaptive_Bit_Model _ctxNumIdcmPointsEq1;
// For bitwise occupancy coding
CtxModelOctreeOccupancy _ctxOccupancy;
// For bytewise occupancy coding
DualLutCoder<true> _bytewiseOccupancyCoder[10];
};
//============================================================================
GeometryOctreeDecoder::GeometryOctreeDecoder(
o3dgc::Arithmetic_Codec* arithmeticDecoder)
: _useBitwiseOccupancyCoder(true), _arithmeticDecoder(arithmeticDecoder)
{}
const GeometryParameterSet& gps, o3dgc::Arithmetic_Codec* arithmeticDecoder)
: _useBitwiseOccupancyCoder(gps.bitwise_occupancy_coding_flag)
, _arithmeticDecoder(arithmeticDecoder)
{
if (!_useBitwiseOccupancyCoder) {
for (int i = 0; i < 10; i++)
_bytewiseOccupancyCoder[i].init(kDualLutOccupancyCoderInit[i]);
}
}
//============================================================================
void
GeometryOctreeDecoder::beginOctreeLevel()
{
for (int i = 0; i < 10; i++) {
_bytewiseOccupancyCoder[i].resetLut();
}
}
//============================================================================
// Decode the number of points in a leaf node of the octree.
......@@ -192,6 +219,18 @@ GeometryOctreeDecoder::decodeOccupancyBitwise(int neighPattern)
return decodeOccupancyNeighNZ(neighPattern10);
}
//-------------------------------------------------------------------------
int
GeometryOctreeDecoder::decodeOccupancyBytewise(int neighPattern)
{
// code occupancy using the neighbour configuration context
// with reduction from 64 states to 10.
int neighPattern10 = kNeighPattern64to10[neighPattern];
auto& bytewiseCoder = _bytewiseOccupancyCoder[neighPattern10];
return bytewiseCoder.decode(_arithmeticDecoder);
}
//-------------------------------------------------------------------------
// decode node occupancy bits
//
......@@ -216,6 +255,8 @@ GeometryOctreeDecoder::decodeOccupancy(int neighPattern)
if (_useBitwiseOccupancyCoder)
mappedOccupancy = decodeOccupancyBitwise(neighPattern);
else
mappedOccupancy = decodeOccupancyBytewise(neighPattern);
return mapGeometryOccupancyInv(mappedOccupancy, neighPattern);
}
......@@ -275,7 +316,7 @@ decodeGeometryOctree(
o3dgc::Arithmetic_Codec* arithmeticDecoder,
pcc::ringbuf<PCCOctree3Node>* nodesRemaining)
{
GeometryOctreeDecoder decoder(arithmeticDecoder);
GeometryOctreeDecoder decoder(gps, arithmeticDecoder);
// init main fifo
// -- worst case size is the last level containing every input poit
......@@ -324,6 +365,8 @@ decodeGeometryOctree(
numNodesNextLvl = 0;
occupancyAtlasOrigin = 0xffffffff;
decoder.beginOctreeLevel();
// allow partial tree encoding using trisoup
if (nodeSizeLog2 == terminalNodeSizeLog2)
break;
......
......@@ -35,6 +35,7 @@
#include "geometry.h"
#include "DualLutCoder.h"
#include "OctreeNeighMap.h"
#include "geometry_octree.h"
#include "io_hls.h"
......@@ -46,7 +47,11 @@ namespace pcc {
class GeometryOctreeEncoder {
public:
GeometryOctreeEncoder(o3dgc::Arithmetic_Codec* arithmeticEncoder);
GeometryOctreeEncoder(
const GeometryParameterSet& gps,
o3dgc::Arithmetic_Codec* arithmeticEncoder);
void beginOctreeLevel();
int encodePositionLeafNumPoints(int count);
......@@ -56,6 +61,8 @@ public:
void encodeOccupancyBitwise(int mappedOccupancy, int neighPattern);
void encodeOccupancyBytewise(int mappedOccupancy, int neighPattern);
void encodeOccupancy(int occupancy, int neighPattern);
void encodePointPosition(int nodeSizeLog2, const PCCVector3<uint32_t>& pos);
......@@ -76,15 +83,36 @@ private:
o3dgc::Adaptive_Bit_Model _ctxPointCountPerBlock;
o3dgc::Adaptive_Bit_Model _ctxBlockSkipTh;
o3dgc::Adaptive_Bit_Model _ctxNumIdcmPointsEq1;
// For bitwise occupancy coding
CtxModelOctreeOccupancy _ctxOccupancy;
// For bytewise occupancy coding
DualLutCoder<true> _bytewiseOccupancyCoder[10];
};
//============================================================================
GeometryOctreeEncoder::GeometryOctreeEncoder(
o3dgc::Arithmetic_Codec* arithmeticEncoder)
: _useBitwiseOccupancyCoder(true), _arithmeticEncoder(arithmeticEncoder)
{}
const GeometryParameterSet& gps, o3dgc::Arithmetic_Codec* arithmeticEncoder)
: _useBitwiseOccupancyCoder(gps.bitwise_occupancy_coding_flag)
, _arithmeticEncoder(arithmeticEncoder)
{
if (!_useBitwiseOccupancyCoder) {
for (int i = 0; i < 10; i++)
_bytewiseOccupancyCoder[i].init(kDualLutOccupancyCoderInit[i]);
}
}
//============================================================================
void
GeometryOctreeEncoder::beginOctreeLevel()
{
for (int i = 0; i < 10; i++) {
_bytewiseOccupancyCoder[i].resetLut();
}
}
//============================================================================
// Encode the number of points in a leaf node of the octree.
......@@ -191,6 +219,19 @@ GeometryOctreeEncoder::encodeOccupancyBitwise(
encodeOccupancyNeighNZ(mappedOccupancy, neighPattern10);
}
//-------------------------------------------------------------------------
void
GeometryOctreeEncoder::encodeOccupancyBytewise(
int mappedOccupancy, int neighPattern)
{
// code occupancy using the neighbour configuration context
// with reduction from 64 states to 10.
int neighPattern10 = kNeighPattern64to10[neighPattern];
auto& bytewiseCoder = _bytewiseOccupancyCoder[neighPattern10];
bytewiseCoder.encode(mappedOccupancy, _arithmeticEncoder);
}
//-------------------------------------------------------------------------
// decode node occupancy bits
//
......@@ -215,6 +256,8 @@ GeometryOctreeEncoder::encodeOccupancy(int occupancy, int neighPattern)
if (_useBitwiseOccupancyCoder)
encodeOccupancyBitwise(mappedOccupancy, neighPattern);
else
encodeOccupancyBytewise(mappedOccupancy, neighPattern);
}
//-------------------------------------------------------------------------
......@@ -269,7 +312,7 @@ encodeGeometryOctree(
o3dgc::Arithmetic_Codec* arithmeticEncoder,
pcc::ringbuf<PCCOctree3Node>* nodesRemaining)
{
GeometryOctreeEncoder encoder(arithmeticEncoder);
GeometryOctreeEncoder encoder(gps, arithmeticEncoder);
// init main fifo
// -- worst case size is the last level containing every input poit
......@@ -323,6 +366,8 @@ encodeGeometryOctree(
occupancyAtlasOrigin = 0xffffffff;
nodeSizeLog2--;
encoder.beginOctreeLevel();
// allow partial tree encoding using trisoup
if (nodeSizeLog2 == terminalNodeSizeLog2)
break;
......
......@@ -204,6 +204,9 @@ struct GeometryParameterSet {
// by directly coding the position of isolated points.
bool inferred_direct_coding_mode_enabled_flag;
// Selects between bitwise and bytewise occupancy coding
bool bitwise_occupancy_coding_flag;
// depth of voxels (reconstructed points) in trisoup geometry
int trisoup_depth;
......
......@@ -192,6 +192,7 @@ write(const GeometryParameterSet& gps)
bs.write(gps.geom_unique_points_flag);
bs.write(gps.neighbour_context_restriction_flag);
bs.write(gps.inferred_direct_coding_mode_enabled_flag);
bs.write(gps.bitwise_occupancy_coding_flag);
bs.writeUe(gps.neighbour_avail_boundary_log2);
if (gps.geom_codec_type == GeometryCodecType::kTriSoup) {
......@@ -222,6 +223,7 @@ parseGps(const PayloadBuffer& buf)
bs.read(&gps.geom_unique_points_flag);
bs.read(&gps.neighbour_context_restriction_flag);
bs.read(&gps.inferred_direct_coding_mode_enabled_flag);
bs.read(&gps.bitwise_occupancy_coding_flag);
bs.readUe(&gps.neighbour_avail_boundary_log2);
if (gps.geom_codec_type == GeometryCodecType::kTriSoup) {
......
......@@ -340,6 +340,40 @@ const uint8_t pcc::kOccMapBit7CtxIdx[128 * 4] = {
//============================================================================
const uint8_t pcc::kDualLutOccupancyCoderInit[10][32] = {
/* [0] = */ {1, 2, 3, 4, 5, 7, 8, 10, 12, 16, 17,
20, 32, 42, 44, 48, 49, 64, 65, 68, 76, 80,
115, 128, 136, 160, 163, 168, 192, 207, 224, 240},
/* [1] = */ {1, 2, 3, 4, 5, 6, 8, 10, 12, 14, 15,
16, 17, 19, 20, 21, 32, 34, 48, 64, 68, 69,
84, 85, 128, 136, 160, 162, 192, 194, 243, 250},
/* [2] = */ {1, 3, 4, 8, 10, 11, 13, 16, 18, 20, 21,
29, 40, 42, 48, 51, 64, 80, 81, 84, 85, 124,
128, 138, 142, 144, 163, 168, 192, 197, 213, 215},
/* [3] = */ {1, 2, 3, 4, 5, 11, 16, 17, 21, 34, 42,
43, 64, 68, 69, 76, 80, 81, 84, 85, 128, 136,
138, 142, 160, 168, 208, 212, 221, 223, 232, 245},
/* [4] = */ {2, 8, 10, 17, 19, 21, 32, 34, 42, 47, 48,
63, 64, 65, 69, 81, 84, 85, 87, 113, 136, 138,
160, 162, 168, 170, 234, 243, 245, 248, 250, 255},
/* [5] = */ {16, 29, 31, 64, 69, 80, 84, 85, 87, 93, 95,
102, 113, 117, 119, 125, 127, 168, 170, 174, 213, 215,
221, 223, 239, 242, 245, 247, 252, 253, 254, 255},
/* [6] = */ {1, 2, 3, 4, 5, 8, 10, 16, 17, 21, 31,
32, 34, 42, 48, 64, 68, 69, 80, 81, 84, 85,
128, 130, 136, 138, 160, 162, 168, 170, 212, 253},
/* [7] = */ {1, 2, 4, 5, 8, 10, 11, 16, 20, 21, 23,
34, 42, 43, 53, 63, 64, 69, 77, 81, 84, 85,
93, 128, 130, 138, 160, 168, 170, 171, 213, 247},
/* [8] = */ {5, 17, 21, 23, 29, 42, 64, 65, 69, 80, 84,
85, 87, 93, 126, 127, 130, 136, 138, 151, 162, 168,
170, 171, 190, 205, 213, 223, 239, 252, 253, 254},
/* [9] = */ {16, 19, 63, 68, 93, 95, 96, 118, 119, 126, 127,
162, 174, 187, 191, 197, 216, 217, 219, 221, 223, 236,
239, 245, 246, 247, 250, 251, 252, 253, 254, 255}};
//============================================================================
const uint32_t pcc::kMortonCode256X[256] = {
0x00000000, 0x00000001, 0x00000008, 0x00000009, 0x00000040, 0x00000041,
0x00000048, 0x00000049, 0x00000200, 0x00000201, 0x00000208, 0x00000209,
......
......@@ -86,6 +86,9 @@ extern const uint8_t kOccMapBit5CtxIdx[32 * 9];
extern const uint8_t kOccMapBit6CtxIdx[64 * 6];
extern const uint8_t kOccMapBit7CtxIdx[128 * 4];
// LUT initialisation table
extern const uint8_t kDualLutOccupancyCoderInit[10][32];
//============================================================================
// Mapping of (x,y,z) components to 3D Morton code.
extern const uint32_t kMortonCode256X[256];
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment