Commit d44baa86 authored by David Flynn's avatar David Flynn
Browse files

geom: refactor bitwise occupancy coding ready for bytewise option

This commit prepares for the introduction of selectable bitwise
and bytewise occupancy coding methods.
parent faff67f7
......@@ -54,7 +54,9 @@ public:
int decodeOccupancyNeighNZ(int neighPattern10);
uint32_t decodeGeometryOccupancy(const PCCOctree3Node& node0);
int decodeOccupancyBitwise(int neighPattern);
uint32_t decodeOccupancy(int neighPattern);
PCCVector3<uint32_t> decodePointPosition(int nodeSizeLog2);
......@@ -63,6 +65,9 @@ public:
int nodeSizeLog2, const PCCOctree3Node& node, OutputIt outputPoints);
private:
// selects between the bitwise and bytewise occupancy coders
const bool _useBitwiseOccupancyCoder;
o3dgc::Arithmetic_Codec* _arithmeticDecoder;
o3dgc::Static_Bit_Model _ctxEquiProb;
o3dgc::Adaptive_Bit_Model _ctxSingleChild;
......@@ -77,7 +82,7 @@ private:
GeometryOctreeDecoder::GeometryOctreeDecoder(
o3dgc::Arithmetic_Codec* arithmeticDecoder)
: _arithmeticDecoder(arithmeticDecoder)
: _useBitwiseOccupancyCoder(true), _arithmeticDecoder(arithmeticDecoder)
{}
//============================================================================
......@@ -172,34 +177,47 @@ GeometryOctreeDecoder::decodeOccupancyNeighNZ(int neighPattern10)
return occupancy;
}
//-------------------------------------------------------------------------
int
GeometryOctreeDecoder::decodeOccupancyBitwise(int neighPattern)
{
if (neighPattern == 0) {
return decodeOccupancyNeighZ();
}
// code occupancy using the neighbour configuration context
// with reduction from 64 states to 10.
int neighPattern10 = kNeighPattern64to10[neighPattern];
return decodeOccupancyNeighNZ(neighPattern10);
}
//-------------------------------------------------------------------------
// decode node occupancy bits
//
uint32_t
GeometryOctreeDecoder::decodeGeometryOccupancy(const PCCOctree3Node& node0)
GeometryOctreeDecoder::decodeOccupancy(int neighPattern)
{
// neighbouring configuration with reduction from 64 to 10
int neighPattern = node0.neighPattern;
int neighPattern10 = kNeighPattern64to10[neighPattern];
// decode occupancy pattern
uint32_t occupancy;
if (neighPattern10 == 0) {
if (neighPattern == 0) {
// neighbour empty and only one point => decode index, not pattern
if (_arithmeticDecoder->decode(_ctxSingleChild)) {
uint32_t cnt = _arithmeticDecoder->decode(_ctxEquiProb);
cnt |= _arithmeticDecoder->decode(_ctxEquiProb) << 1;
cnt |= _arithmeticDecoder->decode(_ctxEquiProb) << 2;
occupancy = 1 << cnt;
} else {
occupancy = decodeOccupancyNeighZ();
return occupancy;
}
} else {
occupancy = decodeOccupancyNeighNZ(neighPattern10);
occupancy = mapGeometryOccupancyInv(occupancy, neighPattern);
}
return occupancy;
uint32_t mappedOccupancy;
if (_useBitwiseOccupancyCoder)
mappedOccupancy = decodeOccupancyBitwise(neighPattern);
return mapGeometryOccupancyInv(mappedOccupancy, neighPattern);
}
//-------------------------------------------------------------------------
......@@ -323,7 +341,7 @@ decodeGeometryOctree(
}
// decode occupancy pattern
uint8_t occupancy = decoder.decodeGeometryOccupancy(node0);
uint8_t occupancy = decoder.decodeOccupancy(node0.neighPattern);
assert(occupancy > 0);
......
......@@ -54,7 +54,9 @@ public:
void encodeOccupancyNeighNZ(int mappedOccupancy, int neighPattern10);
void encodeGeometryOccupancy(const PCCOctree3Node& node0, int occupancy);
void encodeOccupancyBitwise(int mappedOccupancy, int neighPattern);
void encodeOccupancy(int occupancy, int neighPattern);
void encodePointPosition(int nodeSizeLog2, const PCCVector3<uint32_t>& pos);
......@@ -64,6 +66,9 @@ public:
const PCCPointSet3& pointCloud);
private:
// selects between the bitwise and bytewise occupancy coders
const bool _useBitwiseOccupancyCoder;
o3dgc::Arithmetic_Codec* _arithmeticEncoder;
o3dgc::Static_Bit_Model _ctxEquiProb;
o3dgc::Adaptive_Bit_Model _ctxSingleChild;
......@@ -78,7 +83,7 @@ private:
GeometryOctreeEncoder::GeometryOctreeEncoder(
o3dgc::Arithmetic_Codec* arithmeticEncoder)
: _arithmeticEncoder(arithmeticEncoder)
: _useBitwiseOccupancyCoder(true), _arithmeticEncoder(arithmeticEncoder)
{}
//============================================================================
......@@ -170,21 +175,30 @@ GeometryOctreeEncoder::encodeOccupancyNeighNZ(
}
//-------------------------------------------------------------------------
// decode node occupancy bits
//
void
GeometryOctreeEncoder::encodeGeometryOccupancy(
const PCCOctree3Node& node0, int occupancy)
GeometryOctreeEncoder::encodeOccupancyBitwise(
int mappedOccupancy, int neighPattern)
{
if (neighPattern == 0) {
encodeOccupancyNeighZ(mappedOccupancy);
return;
}
// code occupancy using the neighbour configuration context
// with reduction from 64 states to 10.
int neighPattern = node0.neighPattern;
int neighPattern10 = kNeighPattern64to10[neighPattern];
encodeOccupancyNeighNZ(mappedOccupancy, neighPattern10);
}
uint32_t mappedOccupancy = mapGeometryOccupancy(occupancy, neighPattern);
//-------------------------------------------------------------------------
// decode node occupancy bits
//
if (neighPattern10 == 0) {
void
GeometryOctreeEncoder::encodeOccupancy(int occupancy, int neighPattern)
{
if (neighPattern == 0) {
bool singleChild = !popcntGt1(occupancy);
_arithmeticEncoder->encode(singleChild, _ctxSingleChild);
......@@ -193,12 +207,14 @@ GeometryOctreeEncoder::encodeGeometryOccupancy(
_arithmeticEncoder->encode(!!(occupancy & 0xaa), _ctxEquiProb); // z
_arithmeticEncoder->encode(!!(occupancy & 0xcc), _ctxEquiProb); // y
_arithmeticEncoder->encode(!!(occupancy & 0xf0), _ctxEquiProb); // x
} else {
encodeOccupancyNeighZ(mappedOccupancy);
return;
}
} else {
encodeOccupancyNeighNZ(mappedOccupancy, neighPattern10);
}
uint32_t mappedOccupancy = mapGeometryOccupancy(occupancy, neighPattern);
if (_useBitwiseOccupancyCoder)
encodeOccupancyBitwise(mappedOccupancy, neighPattern);
}
//-------------------------------------------------------------------------
......@@ -351,7 +367,7 @@ encodeGeometryOctree(
// encode child occupancy map
assert(occupancy > 0);
encoder.encodeGeometryOccupancy(node0, occupancy);
encoder.encodeOccupancy(occupancy, node0.neighPattern);
// when nodeSizeLog2 == 1, children are indivisible (ie leaf nodes)
// and are immediately coded. No further splitting occurs.
......
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