Commit 0a0366d0 authored by Khaled Mammou's avatar Khaled Mammou Committed by David Flynn
Browse files

m42634/attr: reduce contexts and alphabet size to code prediction delta

When coding attribute prediction deltas, this commit implements a scheme
to code the first and subsequent attribute components using each:

 - one 65-ary contexts to code a delta prefix
 - one binary context to code remainder values

This replaces the previous scheme using:

 - one n-ary (max 2048) context to code a delta prefix (first comp.)
 - one binary context to code remainder values         (first comp.)
 - 512 n-ary (max 2048) contexts to code a delta prefix (subsequent comp.)
 - 512 binary contexts to code remainder values         (subsequent comp.)

Extracted-from: http://wg11.sc29.org/svn/repos/MPEG-I/Part5-PointCloudCompression/CE/CE0/CE0.1/trunk@1357


Reintegrated-by: David Flynn's avatar <dflynn@blackberry.com>
parent 51f455d0
......@@ -45,8 +45,6 @@ namespace pcc {
const uint32_t PCCTMC3MagicNumber = 20110904;
const uint32_t PCCTMC3FormatVersion = 1;
const uint32_t PCCTMC3MaxPredictionNearestNeighborCount = 4;
const uint32_t PCCTMC3Diff1AdaptiveDataModelCount = 512;
const uint32_t PCCTMC3AdaptiveDataModelAlphabetMaxSize = 2047;
const int MAX_NUM_DM_LEAF_POINTS = 2;
......
......@@ -51,6 +51,51 @@
namespace pcc {
class PCCTMC3Decoder3 {
struct PCCResidualsDecoder {
uint32_t alphabetSize;
o3dgc::Arithmetic_Codec arithmeticDecoder;
o3dgc::Static_Bit_Model binaryModel0;
o3dgc::Adaptive_Bit_Model binaryModelDiff0;
o3dgc::Adaptive_Data_Model multiSymbolModelDiff0;
o3dgc::Adaptive_Bit_Model binaryModelDiff1;
o3dgc::Adaptive_Data_Model multiSymbolModelDiff1;
PCCResidualsDecoder() { alphabetSize = 0; }
void start(PCCBitstream &bitstream, const uint32_t alphabetSize = 64) {
this->alphabetSize = alphabetSize;
multiSymbolModelDiff0.set_alphabet(alphabetSize + 1);
binaryModelDiff0.reset();
multiSymbolModelDiff1.set_alphabet(alphabetSize + 1);
binaryModelDiff1.reset();
arithmeticDecoder.set_buffer(
static_cast<uint32_t>(bitstream.capacity - bitstream.size),
bitstream.buffer + bitstream.size
);
arithmeticDecoder.start_decoder();
}
void stop() { arithmeticDecoder.stop_decoder(); }
uint32_t decode0() {
uint32_t value = arithmeticDecoder.decode(multiSymbolModelDiff0);
if (value == alphabetSize) {
value += arithmeticDecoder.ExpGolombDecode(
0, binaryModel0, binaryModelDiff0
);
}
return value;
}
uint32_t decode1() {
uint32_t value = arithmeticDecoder.decode(multiSymbolModelDiff1);
if (value == alphabetSize) {
value += arithmeticDecoder.ExpGolombDecode(
0, binaryModel0, binaryModelDiff1
);
}
return value;
}
};
public:
PCCTMC3Decoder3() { init(); }
PCCTMC3Decoder3(const PCCTMC3Decoder3 &) = default;
......@@ -182,165 +227,60 @@ class PCCTMC3Decoder3 {
}
private:
static uint32_t decodeAbsUInt32(const uint32_t bitCount,
o3dgc::Arithmetic_Codec &arithmeticDecoder,
o3dgc::Static_Bit_Model &binaryModel0) {
uint32_t decodedValue = 0;
for (uint32_t i = 0; i < bitCount; ++i) {
decodedValue += (arithmeticDecoder.decode(binaryModel0) << i);
}
return PCCFromLittleEndian<uint32_t>(decodedValue);
}
static uint32_t decodeDiff0UInt32(const uint32_t maxAttributeValueDiff0,
const uint32_t adaptiveDataModelAlphabetSizeDiff0,
o3dgc::Arithmetic_Codec &arithmeticDecoder,
o3dgc::Adaptive_Data_Model &multiSymbolModelDiff0,
o3dgc::Adaptive_Bit_Model &binaryModelDiff0,
o3dgc::Static_Bit_Model &binaryModel0) {
if (!maxAttributeValueDiff0) {
return 0;
} else {
uint32_t value = arithmeticDecoder.decode(multiSymbolModelDiff0);
if (value == adaptiveDataModelAlphabetSizeDiff0) {
value += arithmeticDecoder.ExpGolombDecode(0, binaryModel0, binaryModelDiff0);
}
return value;
}
}
static uint32_t decodeDiff1UInt32(const uint32_t modelIndex,
const uint32_t maxAttributeValueDiff1,
const uint32_t adaptiveDataModelAlphabetSizeDiff1,
o3dgc::Arithmetic_Codec &arithmeticDecoder,
std::vector<o3dgc::Adaptive_Data_Model> &multiSymbolModelDiff1,
std::vector<o3dgc::Adaptive_Bit_Model> &binaryModelDiff1,
o3dgc::Static_Bit_Model &binaryModel0) {
if (!maxAttributeValueDiff1) {
return 0;
} else {
uint32_t value = arithmeticDecoder.decode(multiSymbolModelDiff1[modelIndex]);
if (value == adaptiveDataModelAlphabetSizeDiff1) {
value += arithmeticDecoder.ExpGolombDecode(0, binaryModel0, binaryModelDiff1[modelIndex]);
}
return value;
}
}
int decodeReflectances(PCCBitstream &bitstream, PCCPointSet3 &pointCloud) {
const size_t pointCount = predictors.size();
uint32_t compressedBitstreamSize = 0;
PCCReadFromBuffer<uint32_t>(bitstream.buffer, compressedBitstreamSize, bitstream.size);
uint32_t maxAttributeValueDiff0 = 0;
PCCReadFromBuffer<uint32_t>(bitstream.buffer, maxAttributeValueDiff0, bitstream.size);
uint32_t adaptiveDataModelAlphabetSizeDiff0 = 0;
o3dgc::Adaptive_Bit_Model binaryModelDiff0;
o3dgc::Adaptive_Data_Model multiSymbolModelDiff0;
if (maxAttributeValueDiff0) {
adaptiveDataModelAlphabetSizeDiff0 = 1 + maxAttributeValueDiff0;
if (adaptiveDataModelAlphabetSizeDiff0 > PCCTMC3AdaptiveDataModelAlphabetMaxSize) {
adaptiveDataModelAlphabetSizeDiff0 = PCCTMC3AdaptiveDataModelAlphabetMaxSize;
}
multiSymbolModelDiff0.set_alphabet(adaptiveDataModelAlphabetSizeDiff0 + 1);
binaryModelDiff0.reset();
}
o3dgc::Arithmetic_Codec arithmeticDecoder;
arithmeticDecoder.set_buffer(uint32_t(bitstream.capacity - bitstream.size),
bitstream.buffer + bitstream.size);
arithmeticDecoder.start_decoder();
o3dgc::Static_Bit_Model binaryModel0;
PCCResidualsDecoder decoder;
const uint32_t alphabetSize = 64;
decoder.start(bitstream, alphabetSize);
const size_t pointCount = predictors.size();
for (size_t predictorIndex = 0; predictorIndex < pointCount; ++predictorIndex) {
auto &predictor = predictors[predictorIndex];
uint16_t &reflectance = pointCloud.getReflectance(predictor.index);
const size_t lodIndex = predictor.levelOfDetailIndex;
const int64_t qs = quantizationSteps[lodIndex];
const uint32_t attValue0 = decodeDiff0UInt32(
maxAttributeValueDiff0, adaptiveDataModelAlphabetSizeDiff0, arithmeticDecoder,
multiSymbolModelDiff0, binaryModelDiff0, binaryModel0);
const uint32_t attValue0 = decoder.decode0();
const int64_t quantPredAttValue = predictor.predictReflectance(pointCloud);
const int64_t delta = PCCInverseQuantization(o3dgc::UIntToInt(attValue0), qs);
const int64_t reconstructedQuantAttValue = quantPredAttValue + delta;
reflectance = uint16_t(PCCClip(reconstructedQuantAttValue, int64_t(0),
int64_t(std::numeric_limits<uint16_t>::max())));
}
arithmeticDecoder.stop_decoder();
decoder.stop();
bitstream.size += compressedBitstreamSize;
return 0;
}
int decodeColors(PCCBitstream &bitstream, PCCPointSet3 &pointCloud) {
const size_t pointCount = predictors.size();
uint32_t compressedBitstreamSize = 0;
PCCReadFromBuffer<uint32_t>(bitstream.buffer, compressedBitstreamSize, bitstream.size);
uint32_t maxAttributeValueDiff0 = 0;
PCCReadFromBuffer<uint32_t>(bitstream.buffer, maxAttributeValueDiff0, bitstream.size);
uint32_t maxAttributeValueDiff1 = 0;
PCCReadFromBuffer<uint32_t>(bitstream.buffer, maxAttributeValueDiff1, bitstream.size);
uint32_t adaptiveDataModelAlphabetSizeDiff0 = 0;
o3dgc::Adaptive_Bit_Model binaryModelDiff0;
o3dgc::Adaptive_Data_Model multiSymbolModelDiff0;
if (maxAttributeValueDiff0) {
adaptiveDataModelAlphabetSizeDiff0 = 1 + maxAttributeValueDiff0;
if (adaptiveDataModelAlphabetSizeDiff0 > PCCTMC3AdaptiveDataModelAlphabetMaxSize) {
adaptiveDataModelAlphabetSizeDiff0 = PCCTMC3AdaptiveDataModelAlphabetMaxSize;
}
multiSymbolModelDiff0.set_alphabet(adaptiveDataModelAlphabetSizeDiff0 + 1);
binaryModelDiff0.reset();
}
uint32_t adaptiveDataModelAlphabetSizeDiff1 = 0;
std::vector<o3dgc::Adaptive_Bit_Model> binaryModelDiff1;
std::vector<o3dgc::Adaptive_Data_Model> multiSymbolModelDiff1;
if (maxAttributeValueDiff1) {
adaptiveDataModelAlphabetSizeDiff1 = 1 + maxAttributeValueDiff1;
if (adaptiveDataModelAlphabetSizeDiff1 > PCCTMC3AdaptiveDataModelAlphabetMaxSize) {
adaptiveDataModelAlphabetSizeDiff1 = PCCTMC3AdaptiveDataModelAlphabetMaxSize;
}
multiSymbolModelDiff1.resize(PCCTMC3Diff1AdaptiveDataModelCount);
binaryModelDiff1.resize(PCCTMC3Diff1AdaptiveDataModelCount);
for (size_t m = 0; m < PCCTMC3Diff1AdaptiveDataModelCount; ++m) {
multiSymbolModelDiff1[m].set_alphabet(adaptiveDataModelAlphabetSizeDiff1 + 1);
binaryModelDiff1[m].reset();
}
}
o3dgc::Arithmetic_Codec arithmeticDecoder;
arithmeticDecoder.set_buffer(uint32_t(bitstream.capacity - bitstream.size),
bitstream.buffer + bitstream.size);
arithmeticDecoder.start_decoder();
o3dgc::Static_Bit_Model binaryModel0;
PCCResidualsDecoder decoder;
const uint32_t alphabetSize = 64;
decoder.start(bitstream, alphabetSize);
const size_t pointCount = predictors.size();
for (size_t predictorIndex = 0; predictorIndex < pointCount; ++predictorIndex) {
auto &predictor = predictors[predictorIndex];
PCCColor3B &color = pointCloud.getColor(predictor.index);
const PCCColor3B predictedColor = predictor.predictColor(pointCloud);
const size_t lodIndex = predictor.levelOfDetailIndex;
const int64_t qs = quantizationSteps[lodIndex];
const uint32_t attValue0 = decodeDiff0UInt32(
maxAttributeValueDiff0, adaptiveDataModelAlphabetSizeDiff0, arithmeticDecoder,
multiSymbolModelDiff0, binaryModelDiff0, binaryModel0);
const uint32_t modelIndex = (attValue0 < PCCTMC3Diff1AdaptiveDataModelCount)
? attValue0
: PCCTMC3Diff1AdaptiveDataModelCount - 1;
const uint32_t attValue0 = decoder.decode0();
const int64_t quantPredAttValue = predictedColor[0];
const int64_t delta = PCCInverseQuantization(o3dgc::UIntToInt(attValue0), qs);
const int64_t reconstructedQuantAttValue = quantPredAttValue + delta;
color[0] = uint8_t(PCCClip(reconstructedQuantAttValue, int64_t(0), int64_t(255)));
for (size_t k = 1; k < 3; ++k) {
const uint32_t attValue = decodeDiff1UInt32(
modelIndex, maxAttributeValueDiff1, adaptiveDataModelAlphabetSizeDiff1,
arithmeticDecoder, multiSymbolModelDiff1, binaryModelDiff1, binaryModel0);
const uint32_t attValue = decoder.decode1();
const int64_t quantPredAttValue = predictedColor[k];
const int64_t delta = PCCInverseQuantization(o3dgc::UIntToInt(attValue), qs);
const int64_t reconstructedQuantAttValue = quantPredAttValue + delta;
color[k] = uint8_t(PCCClip(reconstructedQuantAttValue, int64_t(0), int64_t(255)));
}
}
arithmeticDecoder.stop_decoder();
decoder.stop();
bitstream.size += compressedBitstreamSize;
return 0;
}
......
......@@ -78,6 +78,47 @@ struct PCCTMC3Encoder3Parameters {
};
class PCCTMC3Encoder3 {
struct PCCResidualsEncoder {
uint32_t alphabetSize;
o3dgc::Arithmetic_Codec arithmeticEncoder;
o3dgc::Static_Bit_Model binaryModel0;
o3dgc::Adaptive_Bit_Model binaryModelDiff0;
o3dgc::Adaptive_Data_Model multiSymbolModelDiff0;
o3dgc::Adaptive_Bit_Model binaryModelDiff1;
o3dgc::Adaptive_Data_Model multiSymbolModelDiff1;
PCCResidualsEncoder() { alphabetSize = 0; }
void start(PCCBitstream &bitstream, const uint32_t alphabetSize = 64) {
this->alphabetSize = alphabetSize;
multiSymbolModelDiff0.set_alphabet(alphabetSize + 1);
binaryModelDiff0.reset();
multiSymbolModelDiff1.set_alphabet(alphabetSize + 1);
binaryModelDiff1.reset();
arithmeticEncoder.set_buffer(static_cast<uint32_t>(bitstream.capacity - bitstream.size),
bitstream.buffer + bitstream.size);
arithmeticEncoder.start_encoder();
}
uint32_t stop() { return arithmeticEncoder.stop_encoder(); }
void encode0(const uint32_t value) {
if (value < alphabetSize) {
arithmeticEncoder.encode(value, multiSymbolModelDiff0);
} else {
arithmeticEncoder.encode(alphabetSize, multiSymbolModelDiff0);
arithmeticEncoder.ExpGolombEncode(value - alphabetSize, 0, binaryModel0, binaryModelDiff0);
}
}
void encode1(const uint32_t value) {
if (value < alphabetSize) {
arithmeticEncoder.encode(value, multiSymbolModelDiff1);
} else {
arithmeticEncoder.encode(alphabetSize, multiSymbolModelDiff1);
arithmeticEncoder.ExpGolombEncode(value - alphabetSize, 0, binaryModel0, binaryModelDiff1);
}
}
};
public:
PCCTMC3Encoder3() { init(); }
PCCTMC3Encoder3(const PCCTMC3Encoder3 &) = default;
......@@ -219,87 +260,15 @@ class PCCTMC3Encoder3 {
}
private:
static void encodeAbsUInt32(const uint32_t value, const uint32_t bitCount,
o3dgc::Arithmetic_Codec &arithmeticEncoder,
o3dgc::Static_Bit_Model &binaryModel0) {
uint32_t valueToEncode = PCCToLittleEndian<uint32_t>(value);
for (uint32_t i = 0; i < bitCount; ++i) {
arithmeticEncoder.encode(valueToEncode & 1, binaryModel0);
valueToEncode >>= 1;
}
}
static void encodeDiff0UInt32(const uint32_t value, const uint32_t maxAttributeValueDiff0,
const uint32_t adaptiveDataModelAlphabetSizeDiff0,
o3dgc::Arithmetic_Codec &arithmeticEncoder,
o3dgc::Adaptive_Data_Model &multiSymbolModelDiff0,
o3dgc::Adaptive_Bit_Model &binaryModelDiff0,
o3dgc::Static_Bit_Model &binaryModel0) {
if (!maxAttributeValueDiff0) {
return;
} else if (value < adaptiveDataModelAlphabetSizeDiff0) {
arithmeticEncoder.encode(value, multiSymbolModelDiff0);
} else {
arithmeticEncoder.encode(adaptiveDataModelAlphabetSizeDiff0, multiSymbolModelDiff0);
arithmeticEncoder.ExpGolombEncode(value - adaptiveDataModelAlphabetSizeDiff0, 0, binaryModel0,
binaryModelDiff0);
}
}
static void encodeDiff1UInt32(const uint32_t value, const uint32_t modelIndex,
const uint32_t maxAttributeValueDiff1,
const uint32_t adaptiveDataModelAlphabetSizeDiff1,
o3dgc::Arithmetic_Codec &arithmeticEncoder,
std::vector<o3dgc::Adaptive_Data_Model> &multiSymbolModelDiff1,
std::vector<o3dgc::Adaptive_Bit_Model> &binaryModelDiff1,
o3dgc::Static_Bit_Model &binaryModel0) {
if (!maxAttributeValueDiff1) {
return;
} else if (value < adaptiveDataModelAlphabetSizeDiff1) {
arithmeticEncoder.encode(value, multiSymbolModelDiff1[modelIndex]);
} else {
arithmeticEncoder.encode(adaptiveDataModelAlphabetSizeDiff1,
multiSymbolModelDiff1[modelIndex]);
arithmeticEncoder.ExpGolombEncode(value - adaptiveDataModelAlphabetSizeDiff1, 0, binaryModel0,
binaryModelDiff1[modelIndex]);
}
}
int encodeReflectances(const PCCAttributeEncodeParamaters &reflectanceParams,
PCCBitstream &bitstream) {
const size_t pointCount = predictors.size();
uint32_t maxAttributeValueDiff0 = 0;
for (size_t predictorIndex = 0; predictorIndex < pointCount; ++predictorIndex) {
const auto &predictor = predictors[predictorIndex];
if (predictor.maxNeighborCount) {
const int64_t quantAttValue = pointCloud.getReflectance(predictor.index);
const int64_t quantPredAttValue = predictor.predictReflectance(pointCloud);
const uint32_t diffAttValue =
uint32_t(o3dgc::IntToUInt(long(quantAttValue - quantPredAttValue)));
if (maxAttributeValueDiff0 < diffAttValue) {
maxAttributeValueDiff0 = diffAttValue;
}
}
}
uint32_t adaptiveDataModelAlphabetSizeDiff0 = 0;
o3dgc::Adaptive_Bit_Model binaryModelDiff0;
o3dgc::Adaptive_Data_Model multiSymbolModelDiff0;
if (maxAttributeValueDiff0) {
adaptiveDataModelAlphabetSizeDiff0 = 1 + maxAttributeValueDiff0;
if (adaptiveDataModelAlphabetSizeDiff0 > PCCTMC3AdaptiveDataModelAlphabetMaxSize) {
adaptiveDataModelAlphabetSizeDiff0 = PCCTMC3AdaptiveDataModelAlphabetMaxSize;
}
multiSymbolModelDiff0.set_alphabet(adaptiveDataModelAlphabetSizeDiff0 + 1);
binaryModelDiff0.reset();
}
uint64_t startSize = bitstream.size;
bitstream.size += 4; // placehoder for bitstream size
PCCWriteToBuffer<uint32_t>(maxAttributeValueDiff0, bitstream.buffer, bitstream.size);
PCCResidualsEncoder encoder;
const uint32_t alphabetSize = 64;
encoder.start(bitstream, alphabetSize);
o3dgc::Arithmetic_Codec arithmeticEncoder;
arithmeticEncoder.set_buffer(static_cast<uint32_t>(bitstream.capacity - bitstream.size),
bitstream.buffer + bitstream.size);
arithmeticEncoder.start_encoder();
o3dgc::Static_Bit_Model binaryModel0;
const size_t pointCount = predictors.size();
for (size_t predictorIndex = 0; predictorIndex < pointCount; ++predictorIndex) {
const auto &predictor = predictors[predictorIndex];
const size_t lodIndex = predictor.levelOfDetailIndex;
......@@ -309,16 +278,14 @@ class PCCTMC3Encoder3 {
const int64_t quantPredAttValue = predictor.predictReflectance(pointCloud);
const int64_t delta = PCCQuantization(quantAttValue - quantPredAttValue, qs);
const uint32_t attValue0 = uint32_t(o3dgc::IntToUInt(long(delta)));
encodeDiff0UInt32(attValue0, maxAttributeValueDiff0, adaptiveDataModelAlphabetSizeDiff0,
arithmeticEncoder, multiSymbolModelDiff0, binaryModelDiff0, binaryModel0);
const int64_t reconstructedDelta = PCCInverseQuantization(delta, qs);
const int64_t reconstructedQuantAttValue = quantPredAttValue + reconstructedDelta;
const uint16_t reconstructedReflectance = uint16_t(PCCClip(
reconstructedQuantAttValue, int64_t(0), int64_t(std::numeric_limits<uint16_t>::max())));
encoder.encode0(attValue0);
pointCloud.setReflectance(predictor.index, reconstructedReflectance);
}
uint32_t compressedBitstreamSize = arithmeticEncoder.stop_encoder();
uint32_t compressedBitstreamSize = encoder.stop();
bitstream.size += compressedBitstreamSize;
PCCWriteToBuffer<uint32_t>(compressedBitstreamSize, bitstream.buffer, startSize);
return 0;
......@@ -342,71 +309,13 @@ class PCCTMC3Encoder3 {
}
int encodeColors(const PCCAttributeEncodeParamaters &colorParams, PCCBitstream &bitstream) {
const size_t pointCount = predictors.size();
uint32_t maxAttributeValueDiff0 = 0;
uint32_t maxAttributeValueDiff1 = 0;
for (size_t predictorIndex = 0; predictorIndex < pointCount; ++predictorIndex) {
const auto &predictor = predictors[predictorIndex];
if (predictor.maxNeighborCount) {
const PCCColor3B color = pointCloud.getColor(predictor.index);
const PCCColor3B predictedColor = predictor.predictColor(pointCloud);
const int64_t quantAttValue = color[0];
const int64_t quantPredAttValue = predictedColor[0];
const uint32_t diffAttValue =
uint32_t(o3dgc::IntToUInt(long(quantAttValue - quantPredAttValue)));
if (maxAttributeValueDiff0 < diffAttValue) {
maxAttributeValueDiff0 = diffAttValue;
}
for (size_t k = 1; k < 3; ++k) {
const int64_t quantAttValue = color[k];
const int64_t quantPredAttValue = predictedColor[k];
const uint32_t diffAttValue =
uint32_t(o3dgc::IntToUInt(long(quantAttValue - quantPredAttValue)));
if (maxAttributeValueDiff1 < diffAttValue) {
maxAttributeValueDiff1 = diffAttValue;
}
}
}
}
uint32_t adaptiveDataModelAlphabetSizeDiff0 = 0;
o3dgc::Adaptive_Bit_Model binaryModelDiff0;
o3dgc::Adaptive_Data_Model multiSymbolModelDiff0;
if (maxAttributeValueDiff0) {
adaptiveDataModelAlphabetSizeDiff0 = 1 + maxAttributeValueDiff0;
if (adaptiveDataModelAlphabetSizeDiff0 > PCCTMC3AdaptiveDataModelAlphabetMaxSize) {
adaptiveDataModelAlphabetSizeDiff0 = PCCTMC3AdaptiveDataModelAlphabetMaxSize;
}
multiSymbolModelDiff0.set_alphabet(adaptiveDataModelAlphabetSizeDiff0 + 1);
binaryModelDiff0.reset();
}
uint32_t adaptiveDataModelAlphabetSizeDiff1 = 0;
std::vector<o3dgc::Adaptive_Bit_Model> binaryModelDiff1;
std::vector<o3dgc::Adaptive_Data_Model> multiSymbolModelDiff1;
if (maxAttributeValueDiff1) {
adaptiveDataModelAlphabetSizeDiff1 = 1 + maxAttributeValueDiff1;
if (adaptiveDataModelAlphabetSizeDiff1 > PCCTMC3AdaptiveDataModelAlphabetMaxSize) {
adaptiveDataModelAlphabetSizeDiff1 = PCCTMC3AdaptiveDataModelAlphabetMaxSize;
}
multiSymbolModelDiff1.resize(PCCTMC3Diff1AdaptiveDataModelCount);
binaryModelDiff1.resize(PCCTMC3Diff1AdaptiveDataModelCount);
for (size_t m = 0; m < PCCTMC3Diff1AdaptiveDataModelCount; ++m) {
multiSymbolModelDiff1[m].set_alphabet(adaptiveDataModelAlphabetSizeDiff1 + 1);
binaryModelDiff1[m].reset();
}
}
uint64_t startSize = bitstream.size;
bitstream.size += 4; // placehoder for bitstream size
PCCWriteToBuffer<uint32_t>(maxAttributeValueDiff0, bitstream.buffer, bitstream.size);
PCCWriteToBuffer<uint32_t>(maxAttributeValueDiff1, bitstream.buffer, bitstream.size);
PCCResidualsEncoder encoder;
const uint32_t alphabetSize = 64;
encoder.start(bitstream, alphabetSize);
o3dgc::Arithmetic_Codec arithmeticEncoder;
arithmeticEncoder.set_buffer(static_cast<uint32_t>(bitstream.capacity - bitstream.size),
bitstream.buffer + bitstream.size);
arithmeticEncoder.start_encoder();
o3dgc::Static_Bit_Model binaryModel0;
const size_t pointCount = predictors.size();
for (size_t predictorIndex = 0; predictorIndex < pointCount; ++predictorIndex) {
const auto &predictor = predictors[predictorIndex];
const PCCColor3B color = pointCloud.getColor(predictor.index);
......@@ -417,14 +326,9 @@ class PCCTMC3Encoder3 {
const int64_t quantPredAttValue = predictedColor[0];
const int64_t delta = PCCQuantization(quantAttValue - quantPredAttValue, qs);
const uint32_t attValue0 = uint32_t(o3dgc::IntToUInt(long(delta)));
const uint32_t modelIndex = (attValue0 < PCCTMC3Diff1AdaptiveDataModelCount)
? attValue0
: PCCTMC3Diff1AdaptiveDataModelCount - 1;
encodeDiff0UInt32(attValue0, maxAttributeValueDiff0, adaptiveDataModelAlphabetSizeDiff0,
arithmeticEncoder, multiSymbolModelDiff0, binaryModelDiff0, binaryModel0);
const int64_t reconstructedDelta = PCCInverseQuantization(delta, qs);
const int64_t reconstructedQuantAttValue = quantPredAttValue + reconstructedDelta;
encoder.encode0(attValue0);
PCCColor3B reconstructedColor;
reconstructedColor[0] =
uint8_t(PCCClip(reconstructedQuantAttValue, int64_t(0), int64_t(255)));
......@@ -435,15 +339,13 @@ class PCCTMC3Encoder3 {
const int64_t reconstructedDelta = PCCInverseQuantization(delta, qs);
const int64_t reconstructedQuantAttValue = quantPredAttValue + reconstructedDelta;
const uint32_t attValue1 = uint32_t(o3dgc::IntToUInt(long(delta)));
encodeDiff1UInt32(attValue1, modelIndex, maxAttributeValueDiff1,
adaptiveDataModelAlphabetSizeDiff1, arithmeticEncoder,
multiSymbolModelDiff1, binaryModelDiff1, binaryModel0);
encoder.encode1(attValue1);
reconstructedColor[k] =
uint8_t(PCCClip(reconstructedQuantAttValue, int64_t(0), int64_t(255)));
}
pointCloud.setColor(predictor.index, reconstructedColor);
}
uint32_t compressedBitstreamSize = arithmeticEncoder.stop_encoder();
uint32_t compressedBitstreamSize = encoder.stop();
bitstream.size += compressedBitstreamSize;
PCCWriteToBuffer<uint32_t>(compressedBitstreamSize, bitstream.buffer, startSize);
return 0;
......
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