Commit 34da2afb authored by Philip A. Chou's avatar Philip A. Chou Committed by David Flynn
Browse files

m42634/raht: added rahtLeafDecimationDepth control

This commit introduces the rahtLeafDecimationDepth parameter to allow
chroma sub-sampling by decimating the coefficients in the bottom n
levels of the tree.

The default value of 3 provides chroma sub-sampling by a factor of 2
in each dimension.
parent 4a6b1a3d
...@@ -154,6 +154,7 @@ int AttributeDecoder::decodeHeader( ...@@ -154,6 +154,7 @@ int AttributeDecoder::decodeHeader(
transformType = TransformType(transType); transformType = TransformType(transType);
PCCReadFromBuffer<uint8_t>(bitstream.buffer, depthRaht, bitstream.size); PCCReadFromBuffer<uint8_t>(bitstream.buffer, depthRaht, bitstream.size);
PCCReadFromBuffer<uint8_t>(bitstream.buffer, binaryLevelThresholdRaht, bitstream.size);
PCCReadFromBuffer<uint32_t>(bitstream.buffer, quantizationStepRaht, bitstream.size); PCCReadFromBuffer<uint32_t>(bitstream.buffer, quantizationStepRaht, bitstream.size);
return 0; return 0;
} }
...@@ -294,8 +295,9 @@ void AttributeDecoder::decodeReflectancesRaht( ...@@ -294,8 +295,9 @@ void AttributeDecoder::decodeReflectancesRaht(
// Re-obtain weights at the decoder by calling RAHT without any attributes. // Re-obtain weights at the decoder by calling RAHT without any attributes.
float *weight = new float[voxelCount]; float *weight = new float[voxelCount];
int *binaryLayer = new int[voxelCount];
regionAdaptiveHierarchicalTransform( regionAdaptiveHierarchicalTransform(
mortonCode, nullptr, weight, 0, voxelCount, depthRaht); mortonCode, nullptr, weight, binaryLayer, 0, voxelCount, depthRaht);
// Sort integerized attributes by weight // Sort integerized attributes by weight
std::vector<WeightWithIndex> sortedWeight(voxelCount); std::vector<WeightWithIndex> sortedWeight(voxelCount);
...@@ -336,6 +338,7 @@ void AttributeDecoder::decodeReflectancesRaht( ...@@ -336,6 +338,7 @@ void AttributeDecoder::decodeReflectancesRaht(
} }
// De-allocate arrays. // De-allocate arrays.
delete[] binaryLayer;
delete[] mortonCode; delete[] mortonCode;
delete[] attributes; delete[] attributes;
delete[] integerizedAttributes; delete[] integerizedAttributes;
...@@ -375,8 +378,9 @@ void AttributeDecoder::decodeColorsRaht( ...@@ -375,8 +378,9 @@ void AttributeDecoder::decodeColorsRaht(
// Re-obtain weights at the decoder by calling RAHT without any attributes. // Re-obtain weights at the decoder by calling RAHT without any attributes.
float *weight = new float[voxelCount]; float *weight = new float[voxelCount];
int *binaryLayer = new int[voxelCount];
regionAdaptiveHierarchicalTransform( regionAdaptiveHierarchicalTransform(
mortonCode, nullptr, weight, 0, voxelCount, depthRaht); mortonCode, nullptr, weight, binaryLayer, 0, voxelCount, depthRaht);
// Sort integerized attributes by weight // Sort integerized attributes by weight
std::vector<WeightWithIndex> sortedWeight(voxelCount); std::vector<WeightWithIndex> sortedWeight(voxelCount);
...@@ -392,9 +396,15 @@ void AttributeDecoder::decodeColorsRaht( ...@@ -392,9 +396,15 @@ void AttributeDecoder::decodeColorsRaht(
for (int n = 0; n < voxelCount; ++n) { for (int n = 0; n < voxelCount; ++n) {
const uint32_t attValue0 = decoder.decode0(); const uint32_t attValue0 = decoder.decode0();
sortedIntegerizedAttributes[n] = o3dgc::UIntToInt(attValue0); sortedIntegerizedAttributes[n] = o3dgc::UIntToInt(attValue0);
for (int d = 1; d < 3; ++d) { if (binaryLayer[sortedWeight[n].index] >= binaryLevelThresholdRaht) {
const uint32_t attValue1 = decoder.decode1(); for (int d = 1; d < 3; ++d) {
sortedIntegerizedAttributes[voxelCount * d + n] = o3dgc::UIntToInt(attValue1); const uint32_t attValue1 = decoder.decode1();
sortedIntegerizedAttributes[voxelCount * d + n] = o3dgc::UIntToInt(attValue1);
}
} else {
for (int d = 1; d < 3; d++) {
sortedIntegerizedAttributes[voxelCount * d + n] = 0;
}
} }
} }
...@@ -432,6 +442,7 @@ void AttributeDecoder::decodeColorsRaht( ...@@ -432,6 +442,7 @@ void AttributeDecoder::decodeColorsRaht(
} }
// De-allocate arrays. // De-allocate arrays.
delete[] binaryLayer;
delete[] mortonCode; delete[] mortonCode;
delete[] attributes; delete[] attributes;
delete[] integerizedAttributes; delete[] integerizedAttributes;
......
...@@ -99,6 +99,7 @@ private: ...@@ -99,6 +99,7 @@ private:
size_t levelOfDetailCount; size_t levelOfDetailCount;
uint32_t quantizationStepRaht; uint32_t quantizationStepRaht;
uint8_t depthRaht; uint8_t depthRaht;
uint8_t binaryLevelThresholdRaht;
TransformType transformType; TransformType transformType;
}; };
......
...@@ -155,6 +155,10 @@ int AttributeEncoder::encodeHeader( ...@@ -155,6 +155,10 @@ int AttributeEncoder::encodeHeader(
PCCWriteToBuffer<uint8_t>( PCCWriteToBuffer<uint8_t>(
uint8_t(attributeParams.depthRaht), bitstream.buffer, bitstream.size); uint8_t(attributeParams.depthRaht), bitstream.buffer, bitstream.size);
PCCWriteToBuffer<uint8_t>(
uint8_t(attributeParams.binaryLevelThresholdRaht),
bitstream.buffer, bitstream.size);
PCCWriteToBuffer<uint32_t>( PCCWriteToBuffer<uint32_t>(
uint32_t(attributeParams.quantizationStepRaht), uint32_t(attributeParams.quantizationStepRaht),
bitstream.buffer, bitstream.size); bitstream.buffer, bitstream.size);
...@@ -317,6 +321,7 @@ void AttributeEncoder::encodeReflectancesTransformRaht( ...@@ -317,6 +321,7 @@ void AttributeEncoder::encodeReflectancesTransformRaht(
int *integerizedAttributes = new int[voxelCount]; int *integerizedAttributes = new int[voxelCount];
int *sortedIntegerizedAttributes = new int[voxelCount]; int *sortedIntegerizedAttributes = new int[voxelCount];
float *weight = new float[voxelCount]; float *weight = new float[voxelCount];
int *binaryLayer = new int[voxelCount];
// Populate input arrays. // Populate input arrays.
for (int n = 0; n < voxelCount; n++) { for (int n = 0; n < voxelCount; n++) {
...@@ -326,8 +331,9 @@ void AttributeEncoder::encodeReflectancesTransformRaht( ...@@ -326,8 +331,9 @@ void AttributeEncoder::encodeReflectancesTransformRaht(
// Transform. // Transform.
regionAdaptiveHierarchicalTransform( regionAdaptiveHierarchicalTransform(
mortonCode, attributes, weight, mortonCode, attributes, weight, binaryLayer,
1, voxelCount, reflectanceParams.depthRaht); 1, voxelCount, reflectanceParams.depthRaht);
// Quantize. // Quantize.
for (int n = 0; n < voxelCount; n++) { for (int n = 0; n < voxelCount; n++) {
integerizedAttributes[n] = integerizedAttributes[n] =
...@@ -354,7 +360,9 @@ void AttributeEncoder::encodeReflectancesTransformRaht( ...@@ -354,7 +360,9 @@ void AttributeEncoder::encodeReflectancesTransformRaht(
} }
// Re-obtain weights at the decoder by calling Raht without any attributes. // Re-obtain weights at the decoder by calling Raht without any attributes.
regionAdaptiveHierarchicalTransform( regionAdaptiveHierarchicalTransform(
mortonCode, nullptr, weight, 0, voxelCount, reflectanceParams.depthRaht); mortonCode, nullptr, weight, binaryLayer,
0, voxelCount, reflectanceParams.depthRaht);
// Sort integerized attributes by weight. // Sort integerized attributes by weight.
for (int n = 0; n < voxelCount; n++) { for (int n = 0; n < voxelCount; n++) {
sortedWeight[n].weight = weight[n]; sortedWeight[n].weight = weight[n];
...@@ -381,6 +389,7 @@ void AttributeEncoder::encodeReflectancesTransformRaht( ...@@ -381,6 +389,7 @@ void AttributeEncoder::encodeReflectancesTransformRaht(
} }
// De-allocate arrays. // De-allocate arrays.
delete[] binaryLayer;
delete[] mortonCode; delete[] mortonCode;
delete[] attributes; delete[] attributes;
delete[] integerizedAttributes; delete[] integerizedAttributes;
...@@ -420,6 +429,7 @@ void AttributeEncoder::encodeColorsTransformRaht( ...@@ -420,6 +429,7 @@ void AttributeEncoder::encodeColorsTransformRaht(
int *integerizedAttributes = new int[attribCount * voxelCount]; int *integerizedAttributes = new int[attribCount * voxelCount];
int *sortedIntegerizedAttributes = new int[attribCount * voxelCount]; int *sortedIntegerizedAttributes = new int[attribCount * voxelCount];
float *weight = new float[voxelCount]; float *weight = new float[voxelCount];
int *binaryLayer = new int[voxelCount];
// Populate input arrays. // Populate input arrays.
for (int n = 0; n < voxelCount; n++) { for (int n = 0; n < voxelCount; n++) {
...@@ -432,8 +442,9 @@ void AttributeEncoder::encodeColorsTransformRaht( ...@@ -432,8 +442,9 @@ void AttributeEncoder::encodeColorsTransformRaht(
// Transform. // Transform.
regionAdaptiveHierarchicalTransform( regionAdaptiveHierarchicalTransform(
mortonCode, attributes, weight, mortonCode, attributes, weight, binaryLayer,
attribCount, voxelCount, colorParams.depthRaht); attribCount, voxelCount, colorParams.depthRaht);
// Quantize. // Quantize.
for (int n = 0; n < voxelCount; n++) { for (int n = 0; n < voxelCount; n++) {
for (int k = 0; k < attribCount; k++) { for (int k = 0; k < attribCount; k++) {
...@@ -463,17 +474,25 @@ void AttributeEncoder::encodeColorsTransformRaht( ...@@ -463,17 +474,25 @@ void AttributeEncoder::encodeColorsTransformRaht(
assert(detail < std::numeric_limits<uint32_t>::max()); assert(detail < std::numeric_limits<uint32_t>::max());
const uint32_t attValue0 = uint32_t(detail); const uint32_t attValue0 = uint32_t(detail);
encoder.encode0(attValue0); encoder.encode0(attValue0);
for (int d = 1; d < 3; ++d) { if (binaryLayer[sortedWeight[n].index] >= colorParams.binaryLevelThresholdRaht) {
const int64_t detail = o3dgc::IntToUInt(sortedIntegerizedAttributes[voxelCount * d + n]); for (int d = 1; d < 3; ++d) {
assert(detail < std::numeric_limits<uint32_t>::max()); const int64_t detail = o3dgc::IntToUInt(sortedIntegerizedAttributes[voxelCount * d + n]);
const uint32_t attValue1 = uint32_t(detail); assert(detail < std::numeric_limits<uint32_t>::max());
encoder.encode1(attValue1); const uint32_t attValue1 = uint32_t(detail);
encoder.encode1(attValue1);
}
} else {
for (int d = 1; d < 3; d++) {
sortedIntegerizedAttributes[voxelCount * d + n] = 0;
}
} }
} }
// Re-obtain weights at the decoder by calling RAHT without any attributes. // Re-obtain weights at the decoder by calling RAHT without any attributes.
regionAdaptiveHierarchicalTransform( regionAdaptiveHierarchicalTransform(
mortonCode, nullptr, weight, 0, voxelCount, colorParams.depthRaht); mortonCode, nullptr, weight, binaryLayer,
0, voxelCount, colorParams.depthRaht);
// Sort integerized attributes by weight. // Sort integerized attributes by weight.
for (int n = 0; n < voxelCount; n++) { for (int n = 0; n < voxelCount; n++) {
sortedWeight[n].weight = weight[n]; sortedWeight[n].weight = weight[n];
...@@ -510,6 +529,7 @@ void AttributeEncoder::encodeColorsTransformRaht( ...@@ -510,6 +529,7 @@ void AttributeEncoder::encodeColorsTransformRaht(
} }
// De-allocate arrays. // De-allocate arrays.
delete[] binaryLayer;
delete[] mortonCode; delete[] mortonCode;
delete[] attributes; delete[] attributes;
delete[] integerizedAttributes; delete[] integerizedAttributes;
......
...@@ -58,6 +58,7 @@ struct PCCAttributeEncodeParamaters { ...@@ -58,6 +58,7 @@ struct PCCAttributeEncodeParamaters {
size_t searchRange; size_t searchRange;
int quantizationStepRaht; int quantizationStepRaht;
int depthRaht; int depthRaht;
int binaryLevelThresholdRaht;
TransformType transformType; TransformType transformType;
std::vector<size_t> dist2; std::vector<size_t> dist2;
std::vector<size_t> quantizationSteps; std::vector<size_t> quantizationSteps;
......
...@@ -61,7 +61,7 @@ namespace pcc { ...@@ -61,7 +61,7 @@ namespace pcc {
* sorting or bucketing for entropy coding. * sorting or bucketing for entropy coding.
*/ */
void regionAdaptiveHierarchicalTransform( void regionAdaptiveHierarchicalTransform(
long long *mortonCode, float *attributes, float *weight, long long *mortonCode, float *attributes, float *weight, int *binaryLayer,
int attribCount, int voxelCount, int depth) int attribCount, int voxelCount, int depth)
{ {
// Prologue, common to both RAHT and IRAHT: // Prologue, common to both RAHT and IRAHT:
...@@ -170,7 +170,10 @@ void regionAdaptiveHierarchicalTransform( ...@@ -170,7 +170,10 @@ void regionAdaptiveHierarchicalTransform(
float *x1 = new float[attribCount]; float *x1 = new float[attribCount];
// Initialize weights. // Initialize weights.
for (int n = 0; n < voxelCount; n++) weight[n] = 1.0f; for (int n = 0; n < voxelCount; n++) {
weight[n] = 1.0f;
binaryLayer[n] = 0;
}
// Process one level at a time, from leaves (b=0) to root (b=3*depth-1). // Process one level at a time, from leaves (b=0) to root (b=3*depth-1).
for (int b = 0; b < 3 * depth; b++) { for (int b = 0; b < 3 * depth; b++) {
...@@ -204,6 +207,8 @@ void regionAdaptiveHierarchicalTransform( ...@@ -204,6 +207,8 @@ void regionAdaptiveHierarchicalTransform(
weight[i0] = (w0 + w1); weight[i0] = (w0 + w1);
weight[i1] = (w0 + w1); weight[i1] = (w0 + w1);
binaryLayer[i0] = b + 1;
n++; // skip over right sibling n++; // skip over right sibling
} }
} }
......
...@@ -67,7 +67,7 @@ struct MortonCodeWithIndex { ...@@ -67,7 +67,7 @@ struct MortonCodeWithIndex {
}; };
void regionAdaptiveHierarchicalTransform( void regionAdaptiveHierarchicalTransform(
long long *mortonCode, float *attributes, float *weight, long long *mortonCode, float *attributes, float *weight, int *binaryLayer,
int attribCount, int voxelCount, int depth); int attribCount, int voxelCount, int depth);
void regionAdaptiveHierarchicalInverseTransform( void regionAdaptiveHierarchicalInverseTransform(
......
...@@ -205,6 +205,11 @@ bool ParseParameters(int argc, char *argv[], Parameters &params) { ...@@ -205,6 +205,11 @@ bool ParseParameters(int argc, char *argv[], Parameters &params) {
" 0: Nearest neighbour prediction with integer lifting transform\n" " 0: Nearest neighbour prediction with integer lifting transform\n"
" 1: Region Adaptive Hierarchical Transform (RAHT)") " 1: Region Adaptive Hierarchical Transform (RAHT)")
("rahtLeafDecimationDepth",
params_attr.binaryLevelThresholdRaht, 3,
"Sets coefficients to zero in the bottom n levels of RAHT tree. "
"Used for chroma-subsampling in attribute=color only.")
("rahtQuantizationStep", ("rahtQuantizationStep",
params_attr.quantizationStepRaht, 1, params_attr.quantizationStepRaht, 1,
"Quantization step size used in RAHT") "Quantization step size used in RAHT")
......
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