Commit 783d83ab authored by David Flynn's avatar David Flynn
Browse files

geom/m46148: neighbour pattern reduction from N10|7|5 to N9|5|3|2

This proposal reduces the number of neighbour configurations used
in occupancy contextualisation from {10, 10, 10, 10, 10, 10, 7, 5}
to {9, 9, 9, 9, 5, 5, 3, 2} by replacing the 64-to-10, 10-to-7,
and 10-to-5 mapping tables with 64-to-9, 9-to-5, and 9-to-3 tables.
parent f5360960
...@@ -137,7 +137,7 @@ inline NeighPattern64toX& ...@@ -137,7 +137,7 @@ inline NeighPattern64toX&
neighPattern64toR1(const GeometryParameterSet& gps) neighPattern64toR1(const GeometryParameterSet& gps)
{ {
if (!gps.neighbour_context_restriction_flag) if (!gps.neighbour_context_restriction_flag)
return kNeighPattern64to10; return kNeighPattern64to9;
return kNeighPattern64to6; return kNeighPattern64to6;
} }
...@@ -162,14 +162,14 @@ struct CtxModelOctreeOccupancy { ...@@ -162,14 +162,14 @@ struct CtxModelOctreeOccupancy {
class CtxMapOctreeOccupancy { class CtxMapOctreeOccupancy {
public: public:
struct CtxIdxMap { struct CtxIdxMap {
uint8_t b0[10]; uint8_t b0[9];
uint8_t b1[20]; uint8_t b1[18];
uint8_t b2[39]; uint8_t b2[35];
uint8_t b3[76]; uint8_t b3[68];
uint8_t b4[149]; uint8_t b4[69];
uint8_t b5[294]; uint8_t b5[134];
uint8_t b6[391]; uint8_t b6[135];
uint8_t b7[520]; uint8_t b7[136];
}; };
CtxMapOctreeOccupancy(); CtxMapOctreeOccupancy();
......
...@@ -62,7 +62,7 @@ public: ...@@ -62,7 +62,7 @@ public:
int mappedOccAdjGt1); int mappedOccAdjGt1);
int decodeOccupancyNeighNZ( int decodeOccupancyNeighNZ(
int neighPattern10, int neighPattern,
int mappedOccIsPredicted, int mappedOccIsPredicted,
int mappedOccPrediction, int mappedOccPrediction,
int mappedOccAdjGt0, int mappedOccAdjGt0,
...@@ -205,14 +205,22 @@ GeometryOctreeDecoder::decodeOccupancyNeighZ( ...@@ -205,14 +205,22 @@ GeometryOctreeDecoder::decodeOccupancyNeighZ(
int int
GeometryOctreeDecoder::decodeOccupancyNeighNZ( GeometryOctreeDecoder::decodeOccupancyNeighNZ(
int neighPattern10, int neighPattern,
int mappedOccIsPredicted, int mappedOccIsPredicted,
int mappedOccPrediction, int mappedOccPrediction,
int mappedOccAdjGt0, int mappedOccAdjGt0,
int mappedOccAdjGt1) int mappedOccAdjGt1)
{ {
int neighPattern7 = kNeighPattern10to7[neighPattern10]; // code occupancy using the neighbour configuration context
int neighPattern5 = kNeighPattern7to5[neighPattern7]; // with reduction from 64 states to 9 (or 6).
int neighPatternR1 = _neighPattern64toR1[neighPattern];
// int neighPattern9 = kNeighPattern64to9[neighPattern];
int neighPattern5 = kNeighPattern9to5[neighPatternR1];
int neighPattern3 = kNeighPattern9to3[neighPatternR1];
// int neighPattern7 = kNeighPattern10to7[neighPattern10];
// int neighPattern5 = kNeighPattern7to5[neighPattern7];
int occupancy = 0; int occupancy = 0;
int partialOccupancy = 0; int partialOccupancy = 0;
...@@ -221,17 +229,18 @@ GeometryOctreeDecoder::decodeOccupancyNeighNZ( ...@@ -221,17 +229,18 @@ GeometryOctreeDecoder::decodeOccupancyNeighNZ(
// NB: offsets are added since ctxIdxMap is shared between Z and NZ cases. // NB: offsets are added since ctxIdxMap is shared between Z and NZ cases.
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
int idx; int idx;
if (i < 6) { if (i < 4) {
idx = ((neighPattern10 - 1) << i) + partialOccupancy + i + 1; idx = ((neighPatternR1 - 1) << i) + partialOccupancy + i + 1;
} else if (i < 6) {
idx = ((neighPattern5 - 1) << i) + partialOccupancy + i + 1;
} else if (i == 6) { } else if (i == 6) {
idx = ((neighPattern7 - 1) << i) + partialOccupancy + i + 1; idx = ((neighPattern3 - 1) << i) + partialOccupancy + i + 1;
} else if (i == 7) { } else if (i == 7) {
idx = ((neighPattern5 - 1) << i) + partialOccupancy + i + 1; idx = partialOccupancy + i + 1;
} else { } else {
// work around clang -Wsometimes-uninitialized fault // work around clang -Wsometimes-uninitialized fault
break; break;
} }
// NB: if firt 7 bits are 0, then the last is implicitly 1. // NB: if firt 7 bits are 0, then the last is implicitly 1.
int bit = 1; int bit = 1;
int bitIsPredicted = (mappedOccIsPredicted >> kOccBitCodingOrder[i]) & 1; int bitIsPredicted = (mappedOccIsPredicted >> kOccBitCodingOrder[i]) & 1;
...@@ -272,11 +281,8 @@ GeometryOctreeDecoder::decodeOccupancyBitwise( ...@@ -272,11 +281,8 @@ GeometryOctreeDecoder::decodeOccupancyBitwise(
mappedOccAdjGt1); mappedOccAdjGt1);
} }
// code occupancy using the neighbour configuration context
// with reduction from 64 states to 10 (or 6).
int neighPatternR1 = _neighPattern64toR1[neighPattern];
return decodeOccupancyNeighNZ( return decodeOccupancyNeighNZ(
neighPatternR1, mappedOccIsPredicted, mappedOccPrediction, mappedOccAdjGt0, neighPattern, mappedOccIsPredicted, mappedOccPrediction, mappedOccAdjGt0,
mappedOccAdjGt1); mappedOccAdjGt1);
} }
......
...@@ -63,7 +63,7 @@ public: ...@@ -63,7 +63,7 @@ public:
int mappedOccAdjGt1); int mappedOccAdjGt1);
void encodeOccupancyNeighNZ( void encodeOccupancyNeighNZ(
int neighPattern10, int neighPattern,
int mappedOccupancy, int mappedOccupancy,
int mappedOccIsPredicted, int mappedOccIsPredicted,
int mappedOccPrediction, int mappedOccPrediction,
...@@ -208,27 +208,37 @@ GeometryOctreeEncoder::encodeOccupancyNeighZ( ...@@ -208,27 +208,37 @@ GeometryOctreeEncoder::encodeOccupancyNeighZ(
void void
GeometryOctreeEncoder::encodeOccupancyNeighNZ( GeometryOctreeEncoder::encodeOccupancyNeighNZ(
int neighPattern10, int neighPattern,
int mappedOccupancy, int mappedOccupancy,
int mappedOccIsPredicted, int mappedOccIsPredicted,
int mappedOccPrediction, int mappedOccPrediction,
int mappedOccAdjGt0, int mappedOccAdjGt0,
int mappedOccAdjGt1) int mappedOccAdjGt1)
{ {
int neighPattern7 = kNeighPattern10to7[neighPattern10]; // code occupancy using the neighbour configuration context
int neighPattern5 = kNeighPattern7to5[neighPattern7]; // with reduction from 64 states to 9 (or 6).
int neighPatternR1 = _neighPattern64toR1[neighPattern];
// int neighPattern9 = kNeighPattern64to9[neighPattern];
int neighPattern5 = kNeighPattern9to5[neighPatternR1];
int neighPattern3 = kNeighPattern9to3[neighPatternR1];
// int neighPattern7 = kNeighPattern10to7[neighPattern10];
// int neighPattern5 = kNeighPattern7to5[neighPattern7];
uint32_t partialOccupancy = 0; uint32_t partialOccupancy = 0;
// NB: it is impossible for pattern to be 0 (handled in Z case). // NB: it is impossible for pattern to be 0 (handled in Z case).
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
int idx; int idx;
if (i < 6) { if (i < 4) {
idx = ((neighPattern10 - 1) << i) + partialOccupancy + i + 1; idx = ((neighPatternR1 - 1) << i) + partialOccupancy + i + 1;
} else if (i < 6) {
idx = ((neighPattern5 - 1) << i) + partialOccupancy + i + 1;
} else if (i == 6) { } else if (i == 6) {
idx = ((neighPattern7 - 1) << i) + partialOccupancy + i + 1; idx = ((neighPattern3 - 1) << i) + partialOccupancy + i + 1;
} else if (i == 7) { } else if (i == 7) {
idx = ((neighPattern5 - 1) << i) + partialOccupancy + i + 1; idx = partialOccupancy + i + 1;
} else { } else {
// work around clang -Wsometimes-uninitialized fault // work around clang -Wsometimes-uninitialized fault
break; break;
...@@ -272,11 +282,8 @@ GeometryOctreeEncoder::encodeOccupancyBitwise( ...@@ -272,11 +282,8 @@ GeometryOctreeEncoder::encodeOccupancyBitwise(
return; return;
} }
// code occupancy using the neighbour configuration context
// with reduction from 64 states to 10 (or 6).
int neighPatternR1 = _neighPattern64toR1[neighPattern];
encodeOccupancyNeighNZ( encodeOccupancyNeighNZ(
neighPatternR1, mappedOccupancy, mappedOccIsPredicted, mappedOccPrediction, neighPattern, mappedOccupancy, mappedOccIsPredicted, mappedOccPrediction,
mappedOccAdjGt0, mappedOccAdjGt1); mappedOccAdjGt0, mappedOccAdjGt1);
} }
......
...@@ -38,16 +38,20 @@ ...@@ -38,16 +38,20 @@
// indicates impossible values in the following table // indicates impossible values in the following table
static const int x = 0; static const int x = 0;
const uint8_t pcc::kNeighPattern64to10[64] = { const uint8_t pcc::kNeighPattern64to9[64] = {
0, 1, 1, 2, 1, 3, 3, 4, 1, 3, 3, 4, 2, 4, 4, 5, 1, 3, 3, 4, 3, 6, 0, 1, 1, 1, 1, 2, 2, 3, 1, 2, 2, 3, 1, 3, 3, 4, 1, 2, 2, 3, 2, 5,
6, 7, 3, 6, 6, 7, 4, 7, 7, 8, 1, 3, 3, 4, 3, 6, 6, 7, 3, 6, 6, 7, 5, 6, 2, 5, 5, 6, 3, 6, 6, 7, 1, 2, 2, 3, 2, 5, 5, 6, 2, 5, 5, 6,
4, 7, 7, 8, 2, 4, 4, 5, 4, 7, 7, 8, 4, 7, 7, 8, 5, 8, 8, 9}; 3, 6, 6, 7, 1, 3, 3, 4, 3, 6, 6, 7, 3, 6, 6, 7, 4, 7, 7, 8};
const uint8_t pcc::kNeighPattern64to6[64] = { const uint8_t pcc::kNeighPattern64to6[64] = {
0, 4, 4, x, 4, 2, 2, x, 4, 2, 2, x, x, x, x, x, 5, 3, 3, x, 3, 1, 0, 4, 4, x, 4, 2, 2, x, 4, 2, 2, x, x, x, x, x, 5, 3, 3, x, 3, 1,
1, x, 3, 1, 1, x, x, x, x, x, 5, 3, 3, x, 3, 1, 1, x, 3, 1, 1, x, 1, x, 3, 1, 1, x, x, x, x, x, 5, 3, 3, x, 3, 1, 1, x, 3, 1, 1, x,
x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x}; x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x};
const uint8_t pcc::kNeighPattern9to5[9] = {0, 1, 2, 3, 1, 2, 3, 4, 4};
const uint8_t pcc::kNeighPattern9to3[9] = {0, 1, 1, 2, 2, 1, 2, 2, 2};
const uint8_t pcc::kNeighPattern10to7[10] = {0, 1, 2, 3, 4, 5, 3, 4, 5, 6}; const uint8_t pcc::kNeighPattern10to7[10] = {0, 1, 2, 3, 4, 5, 3, 4, 5, 6};
const uint8_t pcc::kNeighPattern7to5[7] = {0, 1, 2, 1, 4, 4, 3}; const uint8_t pcc::kNeighPattern7to5[7] = {0, 1, 2, 1, 4, 4, 3};
......
...@@ -40,8 +40,10 @@ ...@@ -40,8 +40,10 @@
namespace pcc { namespace pcc {
// Symmetry reduction of 64 neighbour pattern to 10 // Symmetry reduction of 64 neighbour pattern to 10
extern const uint8_t kNeighPattern64to10[64]; extern const uint8_t kNeighPattern64to9[64];
extern const uint8_t kNeighPattern64to6[64]; extern const uint8_t kNeighPattern64to6[64];
extern const uint8_t kNeighPattern9to5[9];
extern const uint8_t kNeighPattern9to3[9];
extern const uint8_t kNeighPattern10to7[10]; extern const uint8_t kNeighPattern10to7[10];
extern const uint8_t kNeighPattern7to5[7]; extern const uint8_t kNeighPattern7to5[7];
......
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